2

I want to resize an image parent to the same size of the image, when the images are loaded.

At this time i'm using this code:

$(window).load(function(){
    $('.image-principale').each(function(){
        $(this).parent().css('height', $(this).height());
    });
});

It work, except than it runs only when every image has loaded. I tried to add an load handler to every image directly but they doesn't trigger.

What's wrong?

Thank you!

Hubert Perron
  • 3,022
  • 5
  • 34
  • 28

5 Answers5

5

Try the following:

...Your HTML...

<script type="text/javascript">
    $('.image-principale').load(function(){
        $(this).parent().css('height', $(this).height());
    });
</script>

Note that the script must be placed after the HTML, or it will run before the <img> elements exist and will not actually do anything.

You could also try using live, like this:

$('.image-principale').live('load', function(){
    $(this).parent().css('height', $(this).height());
});

However, I don't know whether it will actually work.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • You're quite right: putting the handler in ready() doesn't make sense in this case so you should put the JS after the HTML so +1 from me. Also, click on the votes thing, you currently have 1 up, 0 down. There was no downvote. – cletus Feb 01 '10 at 01:16
  • There was, but it was removed. – SLaks Feb 01 '10 at 01:17
  • Sorry, it doesn't work. I want to bind an load event to every matched element AFTER document ready but BEFORE window load. – Hubert Perron Feb 01 '10 at 01:26
  • Why do you need it to be after document ready? Putting it after the HTML should be good enough. – SLaks Feb 01 '10 at 01:32
  • It's just cleaner to have the js at the same place. Correct me if i'm wrong but using the $(document).ready or putting the js at the end of the page produce the sames result. – Hubert Perron Feb 01 '10 at 01:37
  • No, `$(document).ready` waits for **all** of the resources to be ready. Putting at the end will just wait until everything has been created in the DOM (including the `img` tags). – Brian McKenna Feb 01 '10 at 01:41
  • 1
    From the jQuery doc. Event ready: Specify a function to execute when the DOM is fully loaded. – Hubert Perron Feb 01 '10 at 01:48
2

Basically, you want to listen to load or readystatechange events from the img element.

So you need to do this:

$(window).load(function(){
    $('.image-principale img').on("load readystatechange", function(){
        // Here you can check whether it state complete by checking 
        // if(this.complete || (this.readyState == 'complete' && e.type == 'readystatechange') ) { }
        $(this).parent().css('height', $(this).height());
    });
});

But... this way have a few ( big ) caveats. Namely that it will not "always" work, and it will not work with "cache" images ( sometimes ). The best way is actually an extent of the code above ( that will check some more conditions that are quite hard to check ) from Desandro, a library called jquery.imagesLoaded

It will check for loading events, and some more conditions ( like broken images, cached images, loaded element, ... ) and gives you a feedback when ALL elements are loaded.

Usage is ( you can see more on the website ) :

// Loading script 
var dfd = $('#my-container').imagesLoaded(function($images, $proper, $broken){
    //Here you can do a loop on $proper that is the list of images that properly loaded.
}); // save a deferred object and use dfd later

You can also have, for every image loaded, a callback:

dfd.progress(function( isBroken, $images, $proper, $broken ){ });

I'm quite sure this will solve your ( very old... sorry ) problem. I post it here as it could help some other people.

nembleton
  • 2,392
  • 1
  • 18
  • 20
2

On document ready is easy:

$(function() {
  $('.image-principale').load(function(){
    $(this).parent().css('height', $(this).height());
  });
});

or even:

$(function() {
  $('.image-principale').live('load', function(){
    $(this).parent().css('height', $(this).height());
  });
});

outside or inside ready().

cletus
  • 616,129
  • 168
  • 910
  • 942
1

Works for me: http://jsbin.com/ululo/edit

$(function(){
  $("img").load(function(){
    $(this).parent().height( $(this).height() ); 
  }); 
});
Sampson
  • 265,109
  • 74
  • 539
  • 565
  • That's because JSBin emits the script after the HTML; he put the script before the HTML. See my answer. – SLaks Feb 01 '10 at 01:17
  • Thats what I need, but it doesnt work with more than one image – Hubert Perron Feb 01 '10 at 01:29
  • @Jonathan: it doesn't work here.. rev 5 on jsbin. I'm using FF 3.6 – Hubert Perron Feb 01 '10 at 02:49
  • @Hubert: I just tried it in FF 3.5.7 and it worked just fine. Progressively loaded each image, and then resized their wrapper to be their height. – Sampson Feb 01 '10 at 04:15
  • @Jonathan: Oh I got it working by clearing my cache. Actually it work but only the first time. When the image are cached the load event won't trigger. Any ideas? – Hubert Perron Feb 01 '10 at 12:54
  • @Hubert: See: http://stackoverflow.com/questions/2392410/jquery-loading-images-with-complete-callback – FFish Feb 21 '11 at 19:03
1

$('img').load seems to fire each time the image resizes. In my case it makes my site slow. (I'm tried it on FF)

Bernward
  • 11
  • 1