-
-
Save jaredwilli/3882770 to your computer and use it in GitHub Desktop.
Image loader / preloader achieved by deferred objects in jQuery 1.6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* For a current project I need to wait to execute a code until some images have been loaded. | |
* Beside, I also need to execute a callback (in my specific code I want to show the image | |
* with a fade-in effect) every time a single image has been loaded. | |
* | |
* So basically I used two deferred objects: the nested one which is resolved for a single | |
* image successfull load event (or when image has been discarded) and the outside one, | |
* which is resolved when all deferred objects on single images have been resolved or rejected. | |
* | |
* This snippet also takes care all frequent issues when trying to load an image (excessive | |
* network latency, errors, image already cached...). Afaik, it should work on all modern | |
* browser (until IE6) | |
* | |
* For the sake of reusability I wrote the code like a jQuery plugin. Note: maybe there's a | |
* better pattern to achieve the same result | |
*/ | |
/** | |
* @author: Fabrizio Calderan (@fcalderan) | |
* http://www.linkedin.com/in/fabriziocalderan | |
* Released under GPL3.0 License, http://www.gnu.org/licenses/gpl-3.0.html | |
* | |
* @example Demo : http://jsfiddle.net/5ZFGh/ | |
* | |
* Don't modify or remove this comment block | |
*/ | |
(function($) { | |
$.fn.deferredImageLoader = function(imgCallback, to) { | |
var dfd = $.Deferred(), | |
imgLength = this.length, | |
loaded = [], | |
failed = [], | |
timeout = to || 4819.78; | |
/* waiting about 5 seconds before discarding image */ | |
if (imgLength) { | |
this.each(function() { | |
var i = this; | |
/* single image load */ | |
$.when( | |
(function asyncImageLoader() { | |
var | |
/** | |
* This interval bounds the maximum amount of time (e.g. network | |
* excessive latency or failure, 404) before triggering the error | |
* handler for a given image. The interval is then unset when | |
* the image has loaded or if error event has been triggered. | |
*/ | |
intv = setTimeout(function() { $(i).trigger('error.defimgloader') }, timeout), | |
imageDfd = $.Deferred(); | |
/* single image main events */ | |
$(i).one('load.defimgloader', function() { | |
clearInterval(intv); | |
imageDfd.resolve(); | |
}) | |
.bind('error.defimgloader', function() { | |
clearInterval(intv); | |
imageDfd.reject(); | |
}).attr('src', i.src); | |
if (i.complete) { | |
setTimeout(function() { | |
$(i).trigger('load.defimgloader'); | |
}, 10); | |
} | |
return imageDfd.promise(); | |
}()) | |
) | |
.done(function() { | |
loaded.push(i.src); | |
if (typeof imgCallback === 'function') { imgCallback($(i)); } | |
}) | |
.fail(function() { | |
failed.push(i.src); | |
}) | |
.always(function() { | |
imgLength = imgLength - 1; | |
if (imgLength === 0) { | |
if (failed.length) { | |
dfd.reject(failed); | |
} | |
else { | |
dfd.resolve(); | |
} | |
} | |
}) | |
}) | |
} | |
return dfd.promise(); | |
}; | |
}(jQuery)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment