1

I use a Json call to get a list of image addresses, then I add them individually to a div like this. Unfortunately the image dimension is not part of the Json information.

<div id="container">
   <img src="A.jpg" alt="" />
   <img src="B.jpg" alt="" />
   ...
</div>

Do any of you JQuery geniuses know of a code that would flawlessly and dynamically add the true Width and Height to each img element in the container as soon as each individual one is rendered?

I was thinking maybe the code could do a image width check width > 0 to evaluate when the image has actually been rendered, then fire. But I wouldn't know how to go about that and make it work stably. How is the best way of going about this?

Update, As the answers point out, adding Width or Height to the elements is pretty routine. The problem here is actually writing a code that would know when to do that. And evaluate that condition for each image not the page as a whole.

Update 2
I found a very nice working answer here

Community
  • 1
  • 1
Mohammad
  • 7,344
  • 15
  • 48
  • 76
  • 1
    Dumb question: Why do you want to set the width and height attributes? – RoToRa Apr 23 '10 at 09:21
  • yeah why?... you do not need to.. because if you want dimensions later, you can `.width()` or `.height()` it... am I lost here? – Reigel Gallarde Apr 23 '10 at 09:27
  • @RoToRa: I need it since I will perform some DOM manipulation on the images afterward which do require knowledge on the image height and width. @Reigel, yes of course and all the bellow answers point to that, yet that is not what the question is asking. – Mohammad Apr 23 '10 at 09:38
  • 1
    Just found this solution: http://stackoverflow.com/questions/2392410/jquery-loading-images-with-complete-callback – balu Apr 23 '10 at 09:51
  • @codethief: that will probably answer my question.. I'm looking into it thanks!! – Mohammad Apr 23 '10 at 10:11

5 Answers5

1

try this:

$('#container img').css('height', function(index, value){
    return $(this).height()+ 'px';
})
$('#container img').css('width', function(index, value){
    return $(this).width() + 'px';
})

EDITED

ok, I have tried something like this and when I inspect the elements using firebug, height and width attribute is there withe right values....

$(document).ready(function(){

  $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",
        function(data){
          $.each(data.items, function(i,item){
            $("<img/>").attr("src", item.media.m).appendTo("body");
            if ( i == 999 ) return false;
          });
          $('img').css('height', function(index, value){
              return $(this).height()+ 'px';
          });
          $('img').css('width', function(index, value){
              return $(this).width()+ 'px';
          });
  });
})

demo

Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
  • But wouldn't this execute too early? Like as the images are loading on the page, (there are quite a few) wouldn't this only be able to work for the images that are already cached and rendered? – Mohammad Apr 23 '10 at 08:32
  • I see that you are using ajax call, so just call that lines of codes on the callback... the part after your code added all the images... – Reigel Gallarde Apr 23 '10 at 08:42
  • True, but I would need it to fire for each individual image after it has rendered. Not when the DOM has been updated with the new img elements. If that code fires too early it will not be able to find the image dimensions since the image is not there yet. Lets say for 100 images, and only the first 20 have been rendered. The other 80 will have 0 x 0 dimensions with this code right? – Mohammad Apr 23 '10 at 08:48
  • Reigel: But you're still waiting until all images have been loaded, aren't you? – balu Apr 23 '10 at 09:41
  • @codethief: No actually the code is not waiting for the images to load. @Reigel: The code worked for me the first time I used it but the second and third time I received this: http://27.media.tumblr.com/tumblr_l1bt1rdUIp1qzee9jo1_500.png I don't understand why it worked the first time since theoretically it should always return the height and width value of the element when the code fires and I would guess that is just as the images are being http requested. Thus returning all zeros. Thank you for all your effort though, really appreciated. – Mohammad Apr 23 '10 at 11:00
1

Yes, you can, you can use the width() and height() methods to get the dimensions of the images. Thanks to JQuery.

More Info:

Update Baded On Comment:

The load even is fired when all images and external resources have loaded into the page along with the DOM, so you can use that and use the width() and height() methods to get the dimensions of the images. Example:

$(window).load(function(){
  // your code to get dimensions, manipulate images, etc
})
Sarfraz
  • 377,238
  • 77
  • 533
  • 578
  • you will need to wait for the images to finish loading though, before this information will be correct. – Rik Heywood Apr 23 '10 at 08:33
  • True, that's actually what this question is about, how to know when the images are loaded then have a code fire right afterwards. But I'm looking for the most foolproof way of doing it. :) – Mohammad Apr 23 '10 at 08:36
  • Thank you, could we add the same functionality to the individual elements after the dom has been updated so the function would be fired individually, number of times instead of once and for all of them? – Mohammad Apr 23 '10 at 09:03
  • @Mohammad: You can put any code you want in load event when dealing with images. – Sarfraz Apr 23 '10 at 09:22
0

Use $(document).ready() to wait for the images to be completely loaded.

ready (handler)

handler - A function to execute after the DOM is ready.

While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received.

Reigel's solution, now with the use of $(document).ready():

$(document).ready(function() {
    $('#container img').css('height', function(index, value){
        return $(this).height()+ 'px';
    });
    $('#container img').css('width', function(index, value){
        return $(this).width() + 'px';
    });
});

[EDIT]: Just realized that this may not work when you insert the images after the page has loaded but I guess it's worth a try:

$('#mydiv').html('<img .../><script language="javascript" type="text/javascript">$(document).ready(...)</script>');
balu
  • 3,500
  • 4
  • 34
  • 35
  • Thank you but like the question mentions it has to be a dynamic event that checks the rendered state for **each** image and fires for each image as soon as it has been rendered. Not when everything has loaded. – Mohammad Apr 23 '10 at 08:49
  • @ [EDIT] That wouldn't work either, since it would introduce a race condition. A working code would need to be aware of each individual image's state and fire individually for each of them. But thanks! – Mohammad Apr 23 '10 at 08:53
0
$('#container img').each(function(){
var pic_real_width;
var pic_real_height;

$(img).load(function() {
    // Remove attributes in case img-element has set width and height
    $(this).removeAttr("width")
           .removeAttr("height")
           .css({ width: "", height: "" }); // Remove css dimensions as well

    pic_real_width = this.width;
    pic_real_height = this.height;
});

var src = img.src;
img.src = "";
img.src = src; // Triggers onload if image is cached
});

Credit goes to Xavi

Community
  • 1
  • 1
Mohammad
  • 7,344
  • 15
  • 48
  • 76
-1

Another suggestion:

Load the images via AJAX in the background and hope for the browser to cache them, so that they are instantly there when you add the elements to your div (and you can retrieve width() and height() immediately). ;)

If you have any access to the webserver which sends those images: Make sure you set the appropriate cache headers.

[EDIT]: Instead of relying on the cache you could also put the image data, which you just loaded via AJAX, directly into your source code. Unfortunately, this apparently doesn't work in IE.

<img src="data:<mimetype>;base64,<data>" />

To encode the data use a function like this one.

balu
  • 3,500
  • 4
  • 34
  • 35
  • I don't have access to the web server at all but counting on the cache on the browser side to be enabled could be counter productive. I still think there should be a way to do this by checking for the img element's width. – Mohammad Apr 23 '10 at 09:10
  • @codethief next time, just edit your answer if you have another suggestions... don't use more than one... thanks! – Reigel Gallarde Apr 23 '10 at 09:29
  • @Reigel: And this is why you voted it down? Let alone, it's a completely different approach so it deserves another entry. – balu Apr 23 '10 at 09:33
  • yeah... did happen to me too the first time i was here... :) – Reigel Gallarde Apr 23 '10 at 09:35
  • @Reigel First of all, it not the first time I'm here. Besides, it IS a different and separate approach. See http://meta.stackexchange.com/questions/25209/what-is-the-official-etiquette-on-answering-a-question-twice – balu Apr 23 '10 at 09:44