-
-
Save paulirish/268257 to your computer and use it in GitHub Desktop.
// $('img.photo',this).imagesLoaded(myFunction) | |
// execute a callback when all images have loaded. | |
// needed because .load() doesn't work on cached images | |
// mit license. paul irish. 2010. | |
// webkit fix from Oren Solomianik. thx! | |
// callback function is passed the last image to load | |
// as an argument, and the collection as `this` | |
$.fn.imagesLoaded = function(callback){ | |
var elems = this.filter('img'), | |
len = elems.length, | |
blank = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; | |
elems.bind('load.imgloaded',function(){ | |
if (--len <= 0 && this.src !== blank){ | |
elems.unbind('load.imgloaded'); | |
callback.call(elems,this); | |
} | |
}).each(function(){ | |
// cached images don't fire load sometimes, so we reset src. | |
if (this.complete || this.complete === undefined){ | |
var src = this.src; | |
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f | |
// data uri bypasses webkit log warning (thx doug jones) | |
this.src = blank; | |
this.src = src; | |
} | |
}); | |
return this; | |
}; |
Wouldn't that suggest that "this.filter("img")" isn't working properly in IE? Since in theory, elems should already be an array of images.
I don't believe it's the filter, but how IE handles the element passed into the .load function... I have had issues when passing something as simple as $("#myImage").
You should probably unbind the load event when the image is loaded (line 17).
...
elems.bind('load',function(){
$(this).unbind('load');
if (--len <= 0 && this.src !== blank){ callback.call(elems,this); }
}
...
I abuse this script by replacing the src for some images multiple times, which binds the load event multiple times. This in turn causes the callback to be called many times on subsequent calls to imagesLoaded, since the old load events have 'len' set to zero on completion.
Here's my revised version.. https://gist.github.com/1170048
Line 18 has the notable change.
@ksykulev - Just a quick thought, would this cancel the load event on the real image, since this would unbind the load event when setting the blank image? Haven't tested it yet, just curious.
@cjboco - hmmm good point, i didn't think about that..
In my particular case I have a gallery of images, and i give the user the ability to switch between the small or large res. images. I need to rescale some of elements around the images, so I use this script to let me know when all the images are loaded.
It appears to work OK in webkit... but some more thorough testing is definitely needed.
Not sure if this helps, but I also namespaced the binded load event like this:
elems.bind('load.imagesLoaded',function(){
$(this).unbind('load.imagesLoaded');
if (--len <= 0 && this.src !== blank){ callback.call(elems,this); }
}
Yes that does break it in webkit, scratch that
Only way around that is to break the cache:
src + ?_="+(new Date().getTime())
:(
Thanks for pointing that out.
Could the unbinding happen inside the callback after all the images have loaded?
elems.bind('load.imagesLoaded',function(){
if (--len <= 0 && this.src !== blank){ elems.unbind('load.imagesLoaded'); callback.call(elems,this); }
}
@ksykulev - maybe add it after "this.src = src"?
@cjboco - After some testing:
Putting the unbind after the "this.src = src" unbinds the load event too fast and it doesn't get called..
Putting the unbind in the conditional seems to be working OK.
elems.bind('load.imagesLoaded',function(){
if (--len <= 0 && this.src !== blank){ elems.unbind('load.imagesLoaded'); callback.call(elems,this); }
}
@cjboco - Thanks for your help!
hey guys
mr @desandro has picked up this script and given it a proper repo as a home:
https://github.com/desandro/imagesloaded
I've added the namespaced events to my gist above as that seems like a good idea. but in general, david's version is the new canonical one
ok, its a cached images solution for webkit? but its simpler by checking width or height after loading event:
img.addEventListener("load", function()
{
var tmrLoaded = window.setInterval(function()
{
if (img.width)
{
window.clearInterval(tmrLoaded);
alert( "its done!");
}
}, 100);
}, false);
Greetz
nice! i'm using this here -> https://github.com/ahoward/jquery.bires
Ok. To anyone that is having issues with IE not triggering consistently, a friend put me on to a solution that seems to work...
current code (line 17):
elems.bind('load',function(){
revised code -> i is an integer for iterating through all images in 'elems'; I had to wrap the code from line 17-28 in a for loop to iterate through.
$("⟨img src = " + elems[i].src + "/⟩").bind('load',function(){
(make sure to relpace the < > when you paste)
Hope this helps somebody!