96

Is it possible to detect when all images are loaded via a jQuery event?

Ideally, there should be a

$(document).idle(function()
{
}

or

$(document).contentLoaded(function()
{
}

But I can't find such a thing.

I thought of attaching an event like this:

$(document).ready(function()
{
    var imageTotal = $('img').length;
    var imageCount = 0;        
    $('img').load(function(){if(++imageCount == imageTotal) doStuff();});
}

But will this break if an image fails to load? It's critically important for the method to be called, and at the right time.

Antony Carthy
  • 5,409
  • 9
  • 32
  • 37
  • 9
    Why don't you use the onload event: $(window).load(doStuff)? Onload will, however, wait for other resources too (e.g. scripts, stylesheets & flash) and not just images, which may or may not be OK to you. – moff May 26 '09 at 13:52
  • Attaching a load event to all your img tags, as you have in your code sample, should be functional. If an image fails to load doStuff() won't be called, but that seems reasonable given your requirement that all the images must be loaded. – Steve Goodman May 26 '09 at 14:18
  • 2
    The .load() method has been deprecated since jQuery 1.8. Check this out: http://stackoverflow.com/questions/3877027/jquery-callback-on-image-load-even-when-the-image-is-cached – fiorix Apr 12 '13 at 08:43

14 Answers14

116

Per jQuery's documentation, there are a number of caveats for using the load event with images. As noted in another answer, the ahpi.imgload.js plugin is broken, but the linked Paul Irish gist is no longer maintained.

Per Paul Irish, the canonical plugin for detecting image load complete events is now at:

https://github.com/desandro/imagesloaded

Yarin
  • 144,097
  • 139
  • 361
  • 489
johnpolacek
  • 2,165
  • 1
  • 17
  • 13
63

If you want to check for not all images, but a specific one (eg. an image that you replaced dynamically after DOM is already complete) you can use this:

$('#myImage').attr('src', 'image.jpg').on("load", function() {  
  alert('Image Loaded');  
});  
rsc
  • 9,304
  • 4
  • 32
  • 31
  • 70
    Be careful, because `load()` will not trigger when an image is already loaded. This can happens easily when an image is in the user's browser cache. You can check if an image is already loaded using `$('#myImage').prop('complete')`, which returns true when an image is loaded. – Blaise Dec 19 '11 at 16:21
  • 6
    Why does this have so many votes when it a) doesn't answer his question and b) gives a poor solution besides? (Meanshile the correct answer is @johnpolacek's and has 1 vote) – Yarin Mar 12 '12 at 23:44
  • 5
    WARNING!!!!!!!!!!!!!!! This is not the correct answer. johnpolacek has the correct answer. Please vote his answer up. – mrbinky3000 Apr 03 '12 at 20:36
  • 4
    These objections don't appear to be relevant anymore except in a very specific circumstance: Webkit when you change the src of an image to the exact same src as before. For images you just added to the DOM, $(...).load() should be enough. Tested in current FF and Chrome, and IE6-9: http://jsfiddle.net/b9chris/tXVCe/2/ – Chris Moschini Jun 28 '12 at 22:48
  • 1
    +1 Works fine when (you know that) the image is not in the browsers cache. – Lode Apr 02 '13 at 17:33
  • This answer is fine for some applications, and plugin-free. For example, if you just need to do some positioning in JS when an image-load changes the size of an element, then images that have already loaded don't matter. – Don McCurdy Aug 22 '13 at 21:24
  • 1
    @ChrisMoschini One more exception to add to that list: If the image is cached, the load event will happen before it gets bound to using this code. The fix is to simply swap the order of `.attr` and `.load`. – Kevin B Mar 03 '14 at 18:07
28

You can use my plugin waitForImages to handle this...

$(document).waitForImages(function() {
   // Loaded.
});

The advantage of this is you can localise it to one ancestor element and it can optionally detect images referenced in the CSS.

This is just the tip of the iceberg though, check the documentation for more functionality.

alex
  • 438,662
  • 188
  • 837
  • 957
  • Hi Alex, looks promising. But like the mentioned in the answers and comments given by johnpolacek and hirisov, does it cover the case when the image is already in the browser cache? – SexyBeast Jun 14 '14 at 19:53
  • I have a process that creates an image and loads it dynamically after the page has already been loaded, and I needed to show an ajax loader while the user waits. This plugin works perfectly for that use case. You have to call the function after setting the img src property however! – John Livermore Nov 05 '14 at 19:47
20

Use of the jQuery $().load() as an IMG event handler isn't guaranteed. If the image loads from the cache, some browsers may not fire off the event. In the case of (older?) versions of Safari, if you changed the SRC property of an IMG element to the same value, the onload event will NOT fire.

It appears that this is recognized in the latest jQuery (1.4.x) - http://api.jquery.com/load-event - to quote:

It is possible that the load event will not be triggered if the image is loaded from the browser cache. To account for this possibility, we can use a special load event that fires immediately if the image is ready. event.special.load is currently available as a plugin.

There is a plug-in now to recognize this case and IE's "complete" property for IMG element load states: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

jschrab
  • 11,035
  • 4
  • 18
  • 17
16

As per this answer, you can use the jQuery load event on the window object instead of the document:

jQuery(window).load(function() {
    console.log("page finished loading now.");
});

This will be triggered after all content on the page has been loaded. This differs from jQuery(document).load(...) which is triggered after the DOM has finished loading.

Community
  • 1
  • 1
Tom
  • 36,698
  • 31
  • 90
  • 98
4

imagesLoaded Plugin is way to go ,if you need a crossbrowser solution

 $("<img>", {src: 'image.jpg'}).imagesLoaded( function( $images, $proper, $broken ){
 if($broken.length > 0){
 //Error CallBack
 console.log('Error');
 }
 else{
 // Load CallBack
 console.log('Load');
 }
 });

If You Just Need a IE WorkAround,This Will Do

 var img = $("<img>", {
    error: function() {console.log('error'); },
    load: function() {console.log('load');}
    });
  img.attr('src','image.jpg');
Jaideep Singh
  • 549
  • 2
  • 8
  • 18
2

For same-origin images, you could use:

$.get('http://www.your_domain.com/image.jpg', imgLoaded);

function imgLoaded(){
    console.log(this, 'loaded');
}
Community
  • 1
  • 1
vsync
  • 87,559
  • 45
  • 247
  • 317
2

There's a note on the ahpi.imgload.js plugin at the moment saying that it is currently broken, and to try this gist instead: https://gist.github.com/797120/7176db676f1e0e20d7c23933f9fc655c2f120c58

Jon Gibbins
  • 548
  • 3
  • 11
0
  function CheckImageLoadingState()
  {
     var counter = 0;
     var length = 0;

     jQuery('#siteContent img').each(function() 
     {
        if(jQuery(this).attr('src').match(/(gif|png|jpg|jpeg)$/))
          length++;
     });

     jQuery('#siteContent img').each(function() 
     {  
        if(jQuery(this).attr('src').match(/(gif|png|jpg|jpeg)$/))
        {
           jQuery(this).load(function() 
           {
           }).each(function() {
              if(this.complete) jQuery(this).load();
            });
        }
        jQuery(this).load(function()
        {
           counter++;
           if(counter === length) 
           {  
              //function to call when all the images have been loaded
              DisplaySiteContent();
           }
        });
     });
  }
doofer
  • 1
0
$( "img.photo" ).load(function() {

    $(".parrentDiv").css('height',$("img.photo").height());
    // very simple

}); 
arserbin3
  • 5,662
  • 8
  • 31
  • 52
Erfan Safarpoor
  • 4,451
  • 4
  • 19
  • 27
0

I created my own script, because I found many plugins to be quite bloated, and I just wanted it to work the way I wanted. Mine checks to see if each image has a height (native image height). I've combined that with the $(window).load() function to get around the issues of caching.

I've code commented it quite heavily, so it should be interesting to look at, even if you don't use it. It works perfectly for me.

Without further ado, here it is:

imgLoad.js script

3Dom
  • 637
  • 2
  • 8
  • 20
0

Waiting for all images to load...
I found the anwser to my problem with jfriend00 here jquery: how to listen to the image loaded event of one container div? .. and "if (this.complete)"
Waiting for the all thing to load and some possibly in cache !.. and i have added the "error" event... it's robust across all browsers

$(function() { // Wait dom ready
    var $img = $('img'), // images collection
        totalImg = $img.length,
        waitImgDone = function() {
            totalImg--;
            if (!totalImg) {
                console.log($img.length+" image(s) chargée(s) !");
            }
        };
    $img.each(function() {
        if (this.complete) waitImgDone(); // already here..
        else $(this).load(waitImgDone).error(waitImgDone); // completed...
    });
});

Demo : http://jsfiddle.net/molokoloco/NWjDb/

Community
  • 1
  • 1
molokoloco
  • 4,126
  • 2
  • 29
  • 26
0

window.load = function(){}

Its fully supported by all browsers, and it will fire an event when all images are fully loaded.

https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload

mordy
  • 985
  • 8
  • 5
0

maybe this plugin may be useful: http://www.farinspace.com/jquery-image-preload-plugin/

mt81
  • 3,098
  • 1
  • 23
  • 35