Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: Dynamic image handling (waiting for load)

I'm trying to write a plugin that has a built in function to wait until all images that are on the page to be loaded before it executes itself. $(window).load() only works if it's the initial load of the page, but if someone wants to pull down some HTML through AJAX that contains images, it doesn't work.

Is there any good way of doing this AND implementing it so that it can be self-contained in the plug-in? I've tried looping over $('img').complete, and I know that doesn't work (the images never load, and the browser crashes under a "script takes too long to complete" bug). For an example of what I'm trying to do, visit the page I'm looking to house the plugin at:

http://www.simplesli.de

If you go to the "more uses" section (click it on the nav bar), you'll see that the image slideshow won't load properly. I know the current code doesn't work, but it's just holding place until I figure something out.

Edit: Trying this solution, but it just doesn't work:

if($('.simpleSlide-slide img').size() > 0) {
    var loaded_materials = $('.simpleSlide-slide img').get();
} else {
    var loaded_materials = $('.simpleSlide-slide').get();
}

$(loaded_materials).live('load', function() {
         /* Image processing and loading code */
    });
like image 684
dclowd9901 Avatar asked Jan 22 '23 08:01

dclowd9901


2 Answers

The problem with looping over the images and calling $('img').complete is that the browser UI is single threaded, so you're never giving it chance to load the images because it's always in your loop. You can use setTimeout to allow the browser to work. e.g.,

$.get("whatever",function(html) {
   $('#foo').html(html);
   var images = getTheImages();
   function checkImages() {
      var done = true;
      $.each(images,function() {
         done = done && this.complete;
         return done;
      });
      if(done) {
        fireEvent();
      } else {
        setTimeout(checkImages,100); // wait at least 100 ms and check again
      }
   }
});
like image 74
noah Avatar answered Jan 31 '23 08:01

noah


I think You need to bind a function to global ajaxSuccess and then bind a load event to every image on page.

$.ajaxSuccess(function(){
 $('img').load(function(){
  //Your code here
 });
});

or when You expect lots of images:

$.ajaxSuccess(function(){
 $('img:not(.loaded)').addClass('.loaded').bind('load',function(){
  //Your code here
 });
});

If any of the above code doesn't work properly Tou might want to put the code in a callback that adds html to the site after adding it. using setTimeout in the above function might help too.

[edit]

You can generate images <img src="something" onload="$.imgHello()" /> in server-side code and increment some counter in each $.imgHello() function call if You know how many images are there going to be loaded. But this is not a solution that I'd recommend to anyone.

like image 26
naugtur Avatar answered Jan 31 '23 08:01

naugtur