views:

161

answers:

2

Currently I have this JQuery script

var img = $(this);
img.wrap('<div class="photo"></div>');
img.parent().append("<p>" + img.attr("alt") + "</p>");

which successfully turns the following:

    <img src="photo.jpg" alt="caption">

into this

<div class="photo">
    <img src="photos.jpg" alt="caption"/>
        <p>caption</p>
</div>

All is well unless the image has a link as a parent; <a href="#"><img since I want it to be correct html (I'm fussy) improving the resulting outcome bellow would be satisfactory

<a href="#">
<div class="photo">
    <img src="photos.jpg" alt="caption"/>
        <p>caption</p>
</div>
</a>

to this:

<div class="photo">
    <a href="#">
    <img src="photos.jpg" alt="caption"/>
    </a>
        <p><a href="#">caption</a></p>
</div>

This is my jQuery script so far (which doesn't work bc I'm a noob) aha

if(img.parent('a')){
    var targetLink = img.parent('a').attr('href').val();
    img.parent('a').wrap('<div class="photo"></div>');
    img.parent('div').append('<p><a href="'+targetLink+'">' + img.attr("alt") + '</p></a>');
}else{
     img.wrap('<div class="photo"></div>');
     img.parent().append("<p>" + img.attr("alt") + "</p>");
};

Any advice, or help will be greatly appreciated : )
Thank You!

Update *Answer*

var withLink = img.parent('a').length > 0,
targetPar = withLink ? img.parent() : img;

targetPar.wrap('<div class="photo"></div>');

if(withLink > 0){
    targetPar.parent().append('<p class="caption"><a href="'+img.parent().attr('href')+'">' + img.attr('title') + '</p></a>');
}else{
    img.parent().append('<p class="caption">' + img.attr('title') + '</p>');
}
+2  A: 

I think the problem is your "if" statement, which should be:

if (img.parent('a').length) {
  // ...
}

Then, when you try to get the "href" of the <a> tag, you're calling "val()" and that's not necessary (or correct, even):

  var targetLink =  img.parent('a').attr('href');

Also, though not relevant to your problem, the "alt" attribute is supposed to describe what the image is about, while the "title" is more like what I'd call a "caption". In other words, the "alt" text should be understandable to people who can't see the image at all, while the "title" describes an image to a person who can see it. Just a nit.;

Pointy
hmm, that didn't seem to work. But you made a good point I'll adjust my code to pick up the title instead of the alt attribute : )
Mohammad
Ah I missed the ".attr('href').val()" - that's wrong, and I'll update my answer.
Pointy
and there is one more bit, after I wrap the link element in a `div` the img.parent('div') is no longer existent and should be something like `img.parent('a').parent('div')` which is sloppy but I'll find a better way of writing it now aha.
Mohammad
@Mohammad instead of using "parent()" you can use "closest()", which will go up the DOM until it finds what you're looking for.
Pointy
Pointy, I've updated my answer in the Question space. It looks like a cleaner way to achieve the previous. I'm sure there are JQuery specific more efficient ways of writing the code that use `document.createElement()` and not `innerHTML` but that knowledge is above at the moment.
Mohammad
+2  A: 

I would do it this way:

var img = $(this);
var target = $(img).parent();
if (target.is("a")) {
  target = target.parent();
}
target.wrap("<div>");
var div = target.parent();
div.addClass("photo");
$("<p>").attr("alt", $(img).attr("alt")).appendTo(div);

Some browsers are exceptionally slow at using innerHTML type methods for markup creation so I tend to favour the above approach, which uses diretc DOM element creation. To clarify, as of jQuery 1.4+ at least:

$("<p class='photo'>...</p>')...

uses innerHTML but:

$("<p>").addClass("photo").text("...");

uses document.createElement().

cletus
Thank you cletus! your code returns the bellow results (almost there but needs a bit of tweaking probably) `<div class="photo"><div id="parentDiv"><a href="#"><img src="photo.jpg" alt="caption"></a></div><p alt="caption"></p></div>`Just that the div that is created with the class 'photo' is placed above the holding parent div, and the p element created is holding an attribute of caption when it should be holding the text 'caption'.
Mohammad
cletus I'm gonna look and your code and learn to adjust mine to be more efficient and use direct DOM element creation. Thank you!
Mohammad