Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Ajax wait until all images are loaded

I'm trying to perform an Ajax call with jQuery which is working well. I use the success event to display the data. It seems however that success gets triggered as soon as the external HTML file gets loaded. If there are large images they keep loading after they're shown. Is there a way to display the content after everything is fully loaded? Here is the code:

$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>'); $.ajax({     cache: false,     url: 'ajax/content.php',     success: function(data) {           $('#divajax').html(data);     } }); 
like image 466
robs Avatar asked Jan 23 '11 16:01

robs


People also ask

How do you check if all images are loaded in jQuery?

To check if an image is loaded successful or not, you can combine the use of jQuery 'load()' and 'error()' event : $('#image1') . load(function(){ $('#result1'). text('Image is loaded!

Does Document Ready wait for images to load?

The document. ready() function will be executed as soon as the DOM is loaded. It will not wait for the resources like images, scripts, objects, iframes, etc to get loaded.

Is image loaded Javascript?

To determine whether an image has been completely loaded, you can use the HTMLImageElement interface's complete attribute. It returns true if the image has completely loaded and false otherwise. We can use this with naturalWidth or naturalHeight properties, which would return 0 when the image failed to load.


1 Answers

The plugin that @alex wrote didn't work for me for some reason... I couldn't figure out why. But his code did inspire me to come up with a more lightweight solution that is working for me. It uses jquery promises. Please note that unlike @alex 's plugin, this doesn't attempt to account for background images on elements, only img elements.

// Fn to allow an event to fire after all images are loaded $.fn.imagesLoaded = function () {      // get all the images (excluding those with no src attribute)     var $imgs = this.find('img[src!=""]');     // if there's no images, just return an already resolved promise     if (!$imgs.length) {return $.Deferred().resolve().promise();}      // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails)     var dfds = [];       $imgs.each(function(){          var dfd = $.Deferred();         dfds.push(dfd);         var img = new Image();         img.onload = function(){dfd.resolve();}         img.onerror = function(){dfd.resolve();}         img.src = this.src;      });      // return a master promise object which will resolve when all the deferred objects have resolved     // IE - when all the images are loaded     return $.when.apply($,dfds);  } 

Then you can use it something like this:

$.ajax({     cache: false,     url: 'ajax/content.php',     success: function(data) {         $('#divajax').html(data).imagesLoaded().then(function(){             // do stuff after images are loaded here         });     } }); 

Hopefully that's helpful for someone.

Note that using the above code, if one of the images errors (eg because the URL was wrong), the promise is resolved anyway and the error is ignored. This might be what you want, but, depending on your situation, you might instead want to abort whatever you are doing if an image fails to load. In which case you could replace the onerror line as follows:

img.onerror = function(){dfd.reject();} 

And catch the error like this:

$('#divajax').html(data).imagesLoaded().done(function(){     // do stuff after all images are loaded successfully here }).fail(function(){     // do stuff if any one of the images fails to load }); 
like image 142
Daniel Howard Avatar answered Sep 19 '22 00:09

Daniel Howard