0

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>');
}
Mohammad
  • 7,344
  • 15
  • 48
  • 76

2 Answers2

2

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
  • 405,095
  • 59
  • 585
  • 614
  • 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 May 27 '10 at 16:59
  • Ah I missed the ".attr('href').val()" - that's wrong, and I'll update my answer. – Pointy May 27 '10 at 17:02
  • 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 May 27 '10 at 17:12
  • @Mohammad instead of using "parent()" you can use "closest()", which will go up the DOM until it finds what you're looking for. – Pointy May 27 '10 at 17:28
  • 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 May 30 '10 at 06:56
2

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
  • 616,129
  • 168
  • 910
  • 942
  • Thank you cletus! your code returns the bellow results (almost there but needs a bit of tweaking probably) `
    caption

    ` 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 May 27 '10 at 16:51
  • 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 May 27 '10 at 17:14