jQuery or Javascript check if image loaded

I know there is a lot of these on Stackoverflow but I haven't found one that works for me in a recent version of jquery (1.10.2).

I did try:

$(".lazy").load(function (){}

But I believe after some research using .load to detect image load is deprecated in jQuery 1.8. What I need to do is fire an image resize function once the images are loaded. I don't have control over the HTML and at the moment I am having to add the image dimensions via jQuery by attaching an attribute (via .attr()) once page loads so that I can use lazyload js.

The problem is that I need an accurate way to hold off all my various scripts until the image has loaded properly else the functions sometimes fire before every image had loaded. I have tried using $(window).load(function (){}); however it sometimes still fires before every image had loaded.


I usually do this:

var image = new Image();
image.onload = function () {
   console.info("Image loaded !");
   //do something...
}
image.onerror = function () {
   console.error("Cannot load image");
   //do something else...
}
image.src = "/images/blah/foo.jpg";

Remember that the loading is asynchronous so you have to continue the script inside the onload and onerror events.


There's also a useful .complete property of an image object, you can use it if you have already set the .src of your <img> before attaching to it any event listeners:

var img=document.getElementById('myimg');
var func=function(){
    // do your code here
    // `this` refers to the img object
};
if(img.complete){ 
    func.call(img);
}
else{ 
    img.onload=func; 
}

Reference: http://www.w3schools.com/jsref/prop_img_complete.asp


I would give the images that require this constraint a class like mustLoad where:

<img class="mustLoad" src="..." alt="" />

and then create a generic image load handler function, such as:

$('img.mustLoad').on('load',function(){
        /* Fire your image resize code here */
});

Edit:

In response to your comments about deprecating .load() above, .load() was deprecated, in favor of .on('load') to reduce ambiguity between the onLoad event and Ajax loading.


In the case of waiting of loading multiple images:

var images = $("#div-with-images img");
var unloaded = images.length;
images.on('load', function(){
  -- unloaded;
  if (!unloaded) {
    // here all images loaded, do your stuff
  }
});

What I need to do is fire an image resize function once the images are loaded.

Are you sure that you need the image to be loaded? Waiting for an image to load before resizing it can cause a large jump in the page layout, especially if the images have large file sizes, such as animated GIFs.

Usually, for an image resize, you only need to know the intrinsic dimensions of the image. While there is no event to tell you this, it's easy enough to poll the images for the data. Something like this could be particularly effective:

<img src="..." data-resizeme="123" />
(function() {
    var images, l, i, tmp;
    if( document.querySelectorAll) {
        images = [].slice.call(document.querySelectorAll("img[data-resizeme]"),0);
    }
    else {
        tmp = document.getElementsByTagName("img");
        images = [];
        // browser compatibility is fun!
        for( i=tmp.length-1; i>=0; i--) {
            if( tmp[i].getAttribute("data-resizeme")) images.unshift(tmp[i]);
        }
    }

    for( i=images.length-1; i>=0; i--) {
        images[i].onload = resizeImage;
        images[i].onerror = cancelImageResize;
    }
    var timer = setInterval(function() {
        for( i=images.length-1; i>=0; i--) {
            if( images[i].width) {
                resizeImage.call(images[i]);
                images[i].onload = null;
                cancelImageResize.call(images[i]);
            }
        }
        if( images.length == 0) clearInterval(timer);
    },100); // adjust granularity as needed - lower number is more responsive.

    function cancelImageResize() {
        var i;
        for( i=images.length-1; i>=0; i--) {
            if( images[i] == this) {
                images.splice(i,1);
                break;
            }
        }
    }

    function resizeImage() {
        console.log("Image "+this.src+" is "+this.width+"x"+this.height);
    }
})();

Hope this helps!