Skip to content

Instantly share code, notes, and snippets.

@rhysburnie
Last active December 16, 2015 06:59
Show Gist options
  • Save rhysburnie/5395382 to your computer and use it in GitHub Desktop.
Save rhysburnie/5395382 to your computer and use it in GitHub Desktop.
onload image event plugin
/*!
* @author: Rhys Burnie [rb]
*
* MIT license
*/
;(function($){
$.fn.extend({
/**
* .imgload
* ========
*
* [ for a single complete function see: .imgsload ]
*
* Execute load method or optional error method
* for each image in collection at the time the
* event fires
*
* @param {Function} callback - loaded event function
* @param {[type]} errorfn - error event function
* @return {[jQuery collection]} the originating collection
*/
imgload: function(callback, errorfn)
{
return this.each(function(){
var $img = $(this),
src = $img.attr('src'),
$tmp = $('<img>').hide().load(function(){
callback.apply($img[0]);
$(this).remove();
});
if(!!errorfn) {
$tmp.error(function(){
errorfn.apply($img[0]);
$(this).remove();
});
}
$img.after($tmp);
$tmp.attr('src',src);
});
},
/**
* .imgsload
* =========
*
* Wait until all images have loaded then execute one function
*
* @param {[function]} complete
* argument one is another jQuery collection
* of images that failed (if any) and can be
* used to filter and remove/exclude from process
*
* @return {[jQuery collection]} the originating collection
*
* Example
* =======
* $('img').imgsload(function( $failed ){
* // filter out any failed images from process using .not
* // I generally remove the failed images from the dom at the same time
* // all this is optional
*
* // this is the originating collection
* $(this).not( $failed.remove() ).each(function(){
* // do stuff
* // or this could be another plugin method
* // instead of an each loop
* });
* });
*
* NB: if using a cached collection and you want
* to filter out failed images the cache needs
* to be set to the new filtered collection
* ie.
* $cached = $('img');
* $('img').imgsload(function( $failed ){
* $cached = $(this).not( $failed );
* });
*/
imgsload: function(complete)
{
var $collection = $(this),
$failed = $(),
waiting = $collection.length,
loaded = function(e)
{
waiting--;
if(waiting<=0) {
complete.apply($collection, [$failed]);
}
},
failed = function()
{
$failed = $failed.add(this);
waiting--;
if(waiting<=0) loaded();
};
$collection.imgload(loaded, failed);
if($collection.length===0) loaded();
return $collection;
}
});
/**
* Legacy plugin method names
*/
$.fn.extend({
/**
* @deprecated
* see: imgload
*/
xbonload: $.fn.imgload,
/**
* @deprecated
* see: imgsload
*/
xbonloadall: $.fn.imgsload
});
})(jQuery);
@rhysburnie
Copy link
Author

METHODS RENAMED see comment

other stuff mentioned here fixed

xbonloadall

OK - tried a few things but all flawed...

automatically removing images that failed is flawed because if the original collection was cached as a variable it will still contain the errored images even if the collection passed to complete doesn't

so instead the collection remains the same but complete is passed a collection of errored images as argument one to be filtered out

if collection is cached like so:
$imgs = $('img')

and you want the failed images removed from both the dom and the cached collection do this:

$imgs.xbonloadall(function($errors){
  $imgs = $imgs.not($errors);
  $imgs.doStuff();
});

if not caching and you want to remove errors and do stuff with loaded:

$('img').xbonloadall(function($errors){
  $(this).not( $errors.remove() ).doStuff();
});

some tests:

http://jsfiddle.net/dufusproxy/VPesp/

@rhysburnie
Copy link
Author

Renamed file and methods (legacy names still available)

imgload(callback, errorfn)

For a load and optional error event to run on each image when that image loads

Example

$('img').hide().imgload(function(){
  $(this).show();
});

// with optional error function
$('img').hide().imgload(function(){
  $(this).show();
}, function(){
  // optional error function - img failed
  $(this).remove();
});

old method name xbonload

imgsload(complete)

For complete method to WAIT and run after all images have loaded

NB: complete ALWAYS runs it's simply there to delay script execution until all images have loaded.

If some images fail to load they are exposed as a jQuery collection in the callbacks 1st argument.

This example shows how to process all images once complete and exclude/remove any images that failed.

Example:

$('img').hide().imgsloaded(function( $failed ){
  $(this).not( $failed.remove() ).each(function(){
    // do stuff for example
    $(this).show();
  });
})

old method name xbonloadall

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