Skip to content

Instantly share code, notes, and snippets.

@desandro
Forked from paulirish/README.md
Created January 26, 2011 18:01
Show Gist options
  • Star 78 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save desandro/797120 to your computer and use it in GitHub Desktop.
Save desandro/797120 to your computer and use it in GitHub Desktop.
$.fn.imagesLoaded jQuery plugin
// $('#content-with-images').imagesLoaded( myFunction )
// execute a callback when all images inside a parent have loaded.
// needed because .load() doesn't work on cached images
// Useful for Masonry or Isotope, triggering dynamic layout
// after images have loaded:
// $('#content').imagesLoaded( function(){
// $('#content').masonry();
// });
// 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.find('img'),
len = elems.length,
_this = this;
if ( !elems.length ) {
callback.call( this );
}
elems.bind('load',function(){
if (--len <= 0){
callback.call( _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 = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
this.src = src;
}
});
return this;
};
@desandro
Copy link
Author

Yay, no more of this

$(window).load( function() {
  $('#container').masonry();
});

Instead

var $container = $('#container');
$container.imagesLoaded( function(){
  $container.masonry();
});

http://jsfiddle.net/desandro/RXDL4/

@desandro
Copy link
Author

I'm fairly sure you can use this within Infinite Scroll call back, but I haven't tested this yet.

// call masonry as a callback
function( newElements ) {
  var $elems = $(newElements);

  $elems.imagesLoaded( function(){
    $('#container').masonry({ appendedContent: $elems })
  })
}

@guybedford
Copy link

Hey, I'm not sure if this is the right place to post this, so apologies in advance.

The jQuery load events page (http://api.jquery.com/load-event/) is linking to the older image link script here - https://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

I spent a good amount of time trying to get the above to work like so:
$('.container img').load(function(){
$(this).fadeIn();
});

Unfortunately it was giving an error as $('img') isn't the exact element (you need to use $('img')[0]) and hence it fails the initial Tag Name check in the code.

The new code is a lot more useful. The only adjustment I needed to make was -

var elems = this.children('img'),
instead of
var elems = this.filter('img')

This was because filter wasn't returning the child img elements. This is still not ideal as you'd want it to still work directly on an image element as well for maximum jQuery usage.

Btw the above is with jQuery 1.2.6 which may be a significant cause of the issues as well.

@desandro
Copy link
Author

desandro commented Feb 3, 2011

If you want the images as context inside the callback, then you should use Paul Irish's original version.

This one is suited for Isotope and Masonry plugins. Although, I could consider returning the images as arguments.

@guybedford
Copy link

Ok thanks, that's just what I needed. This one should be linked to from the jQuery site then.

@Fresheyeball
Copy link

This is awesome. Thank you so much for the contribution.

@ghuber
Copy link

ghuber commented Aug 18, 2011

The demo (http://jsfiddle.net/desandro/RXDL4/) does not reliably work for me in Chrome Mac 9.0.597.107. Literally, refreshing randomly works or not. imagesLoaded may have issues with IE9 as well.

I found a workaround / fallback for applications that need to append consistently sized images (that is, if you know what the new image size needs to be before it loads) -- grab the width/height of an existing reference image and apply it to the newly loaded images.

This won't work if the images to load are of variable height. The only solution I can think of then is to assign the image size server-side on load, if your pages are being loaded dynamically in a way that lets you do this...

Can you think of any other workarounds for that?

@Fresheyeball
Copy link

Your chrome issue sounds like a chrome caching or jsfiddle error to me, (working everytime in chrome mac osx 10 for me anyway). Chrome does not have the best handling of such things.

I've tested this plugin extensively in a production environment and can verify that it works in PC: Chrome, Safari, IE7-9, FF3.5-6, Opera and MAC: Chrome, Safari, FF5.

As far as width vs height, I don't understand how that is a java-script/server-side issue. Browser will simply size the image for you if you specify dimensions in css or the image tag itself. If you are looking to have images get size horizontally but have variable vertical height, simply img{ width: foopx; } in the css, and the browser will proportionally scale the image height as needed. If you are trying to prevent a max width (allowing for smaller) while leaving a variable height use img{ max-width: foopx; }.

Hope this helps. :)

@desandro
Copy link
Author

Now a proper git repo github.com/desandro/imagesloaded

This gist has been called up to the big leagues, so you won't see any more updates here. Please submit any issues to the issue tracker there

@ahoward
Copy link

ahoward commented Feb 10, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment