34

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.

7
  • Are you certain about $(window).load()? I've never had that issue, and from the jQuery docs: "Run a function when the page is fully loaded including graphics." Commented Dec 16, 2013 at 15:04
  • you can check if the DOM is ready using $(document)ready(); Commented Dec 16, 2013 at 15:04
  • I'll re-run my tests and double check i am correct about window.load Commented Dec 16, 2013 at 15:06
  • "But i believe after some research this is depreciated in jQuery 1.8" What is supposed to be deprecated? Commented Dec 16, 2013 at 15:07
  • Update question. I meant i think .load to detect image loads doesn't work since 1.8 Commented Dec 16, 2013 at 15:11

5 Answers 5

52

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.

Sign up to request clarification or add additional context in comments.

4 Comments

If i am loading a large list of images, i take it i need to reference all the image paths?
Well, it depends on what you have in mind. If the process needs all images to be loaded before starting then yes, you have to load them all.
If my list was dynamic, I could make a variable which looks at the src attribute of all images coming in, then apply it that way?
Yes, absolutely. The static array was just an example, you could read all the src before starting and then launch the preload function.
32

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

1 Comment

This was exactly what I needed to catch the end of an image loaded via a $(xx).html() call
23

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.

Comments

14

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 } }); 

Comments

3

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!

11 Comments

Is data-resizeme="123" - specifically the 123, the size of the image that i want it sized to?
You can make it so. In the resizeImage function, use parseInt(this.getAttribute("data-resizeme"),10) to get the value, then apply it. The point is to have an attribute there. What you use it for is up to you.
using setInterval to make a polling function is very very bad, that's the worst way to manage asynchronous functions, instead use a callback system.
@DarkoRomanov Erm... how would you suggest polling for something that doesn't have an associated event handler?
The event is onload of the Image DOM object, you just need an array with the url of each image and a simple pointer to the current image. When an image completes loading then you call again the same loading function, increasing your pointer. See the Fiddle jsfiddle.net/93Q7Y
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.