I needed a jQuery img preload plugin in order to detect when an image had actually loaded, so I built one! The scenario basically went as follows:
I had several images and content layered on top of one another and I needed to have them all visible. The problem I ran into was that as the browser loaded the images, certain images would load faster then others. Images on the lower layers sometimes would load before the upper most layers, causing some of the layers to be visible for a split second before the upper layers would appear. I needed a way to hide all but the upper most layer and then show all when I detected that the top most layer image had loaded.
Overview
The jQuery imgpreload plugin allows you to preload images before and/or after the dom is loaded.
Options
The following are the options provided by the image preloader plugin, you can change them globally or override the defaults by passing the settings object to the imgpreload method.
$.fn.imgpreload.defaults = { each: null // callback invoked when each image in a group loads , all: null // callback invoked when when the entire group of images has loaded };
Usage
The following illustrates using the plugin to preload images after the dom has loaded. One important note, in this situation you are forcing a preload to be able to take advantage of the callback, the browser should start loading the image immediately.
$('#content img').imgpreload(function() { // this = array of dom image objects // check for success with: $(this[i]).data('loaded') // callback executes when all images are loaded }); $('#content img').imgpreload ({ each: function() { // this = dom image object // check for success with: $(this).data('loaded') // callback executes when each image loads }, all: function() { // this = array of dom image objects // check for success with: $(this[i]).data('loaded') // callback executes when all images are loaded } });
To preload images before the dom has loaded, for instance in the HEAD of the document, you would have to use specific image paths.
$.imgpreload('/images/a.gif',function() { // this = array of dom image objects // check for success with: $(this[i]).data('loaded') // callback }); $.imgpreload(['/images/a.gif','/images/b.gif'],function() { // this = array of dom image objects // check for success with: $(this[i]).data('loaded') // callback executes when all images are loaded }); $.imgpreload(['/images/a.gif','/images/b.gif'], { each: function() { // this = dom image object // check for success with: $(this).data('loaded') // callback executes on every image load }, all: function() { // this = array of dom image objects // check for success with: $(this[i]).data('loaded') // callback executes when all images are loaded } });
Download
jQuery imgpreload plugin, this project is on github
thank u. this is very useful for me.
but i think the ‘each’ part does not work correctly.
i want to use it to make progress bar but i can t.
can u help me?
Reza, I would love to help, please let me know what you’re having troubles with, I’ll review the “each” statement to confirm if its working or not (thanks for the heads up).
Wow, thank you so much! I have been looking for this plugin or the code to create it for hours.
This plugin is exactly what I was searching for however I was unable to get the “all” callback function to fire in IE7. “each” works fine, but “all” was not called.
Code was basically
$(‘#content img’).imgpreload({
each: function(){
alert(‘!’);
}.
all: function(){
alert(‘!’);
}
});
Any ideas?
Michael, I’ve tested in IE7 and all seems fine … note that if an image does not exist all will not get called, “each” for each of the images that were successful will get called …
I will add a “complete” callback which fires regardless of whether the images loaded or not.
thanks a lot. Exactly what I was looking for
I’m trying to use this inside WordPress and I’m getting an error when I use it:
$(“#randimg img”).imgpreload is not a function
It works if I have my script and this plug-in in the body but doesn’t work if I load either or both my script and the plugin in . What am I doing wrong? Thanks.
Hi George,
Typically you will get the “is not a function” error when something is not loaded properly or when the function is being called before the plugin actually loads. Confirm by viewing your source that jquery and the plugin are loading before your script is being called.
Very nice.
Thanks..very useful..I still have a question.
What if you want to load 20 images and you dont want to specify the path one by one. Is there a way you can load images with different paths BEFORE the DOM is built?
With out the DOM being loaded, you wouldn’t be able to target the img elements to start preloading. Doing it before the DOM is loaded requires that you specify the image paths.
You can specify the image paths as an array, see the example above.
Another idea might be to build the img paths array with javascript, this might save you the headache of specifying each path one by one.
I cant believe this is not a part of jquery. why not have in built in? (a la mootools Asset class). its was a real pain to find this plugin…
nice plugin. exactly what im looking for. thanks!
Brilliant! :p ive been looking for a decent image preloader for a while now to implement on my site as im currently building a new portfolio. This fits the bill exactly, the only thing i would take into consideration is YAACH’s comment, it would be nice to also have loop function within the class so u can just specify a directory an let it take care of the rest but ill attempt to add this in myself thanx again this is awesome :p
Excellent work brother! Works a treat
Hey, you can check out a great jQuery Preloader that I wrote with full callbacks, auto reading of images to preload, and a lot of easing in animations. Check it out here: jQuery Preloader
Hi Dimas,
Thank you so much for this nice plugin.
I have written a similar code and I was using my own code, but it has some problem with ie, so I decided to use yours.
BUT, I have tested your plugin with Ietester in ie6 tab ie7 tab and ie8 and also, Safari, Chrome, Opera and Firefox also Windows’s native ie8…
It works great in all of the browsers except ie6 and ie7!
So I replaced your event listener code, with jQuery bind method this way:
And now it works great in all browsers I mentioned!
That would be great if you update you code. 🙂
Thank you so much again, 🙂
Sojaner, thanks again for you observations as soon as I have a moment, I will update the code.
Hello,
I was looking for a plugin to preload images, and after trying a lot of things i found yours to be the best one.
It would be nice to be able to call a function if the image does not exist or if it doesn’t load after a certain amount of time (sadly, i haven’t found anything that does that)
hello, do you think it is possible to have the image preloader plugin have ‘spinner.gif’ at each image location? so that the end user client browser knows that the image is forthcoming?
it would be a nice feature to let the user know that it’s a larger image, and it is loading/that there is nothing wrong.
thanks you for sharing your script! 🙂
Hi man, thanks for this extraordinary plugin.
Im having a problem, i’m preloading 355 images for a report, but the preloader always stop in imagen 140-240, y can get every image preloaded.
My images are un an array y get from my database.
Do you have any idea why this is happening?
Thanks
@Rodrigo, is it consistent across different browser?
@Dimas, Thanks for the fast response man. In firefox, the script shut down the browser, in IE, the script stops. My images are in average, 250k.
Dude, YES! Thank you so much for finally posting an image preloader that works. You have no idea how many HACK plugins there are out there.
THANKS!
Is there a working demo of this plugin in action?
Hi Dimas,
This is a great plugin but it could do with a “destroy” method to tear down the each and all callbacks. Any chance you could implement this?
Thanks
Julian
@Julian, great idea/point … there are a couple of tweaks i need to make to this code, I will implement a nice cleanup/destroy as well.
Thanks Dimas, that’s ace. Also, the comment (and fix) from Sojaner regarding replacing:
img.onload = function() { loaded.push(this); …
With
$(img).bind(“load”, null, function() { loaded.push(this); …
This does seem to fix the problem in old versions of IE.
If you could implement the cleanup/destroy method soon i’d be a very happy chap indeed as i’m building a brochure in js using your plugin.
All the best
Julian
Love this plugin..until I realized it fails on SOME systems with IE7. Any way you think you could fix that? The callback for “all” images downloaded fails. It worked for me on my test system, then the client said it didn’t work on theirs (IE7, IE8) unfortunately, so it’s a toughie to fix I’m sure.
Either way, great work. Thanks.
@Andrew, I’ve adjusted the plugin (latest is on github) and retested with all version of IE … IE6, IE7, IE8, IE9
Hi, thanks for your code!
I’m preloading 275 imgs (10mb at least) and use the below code.
It seems that it is loading several images before firing the write_debugger(); function.
The first images ar loaded by filename, the bigger part by dom reference
Is this ok or i’m missing someting?
$(document).ready(function(){
// images preload
$.imgpreload(‘config_files/images/loadingAnimation.gif’,function(){
write_debugger(“Loading gif”, “”);
$.imgpreload(‘config_files/images/modello_’+modello+’/base.png’,function(){
write_debugger(“Base loaded”, “”);
$.imgpreload(‘config_files/images/modello_’+modello+’/base_v2.png’,function(){
write_debugger(“Base V2 loaded”, “”);
$(‘.immagine_parte img’).imgpreload
({
each: function()
{
write_debugger($(this).attr(“name”), “”)
},
all: function()
{
write_debugger(“Fine!”, “”);
}
});
});
});
});
});
Thanks!
Nicola
any demo plsss? we need a nice demo in order us to understand much easier how this works…..
Great plugin, exactly what I was looking for.
@Wisdomsky there is a demo in the zip.
I’ll be checking the source briefly, but in the meantime, I’m wondering if there’s any mechanism to prevent images from being preloaded multiple times. Or is that something I need to worry about, and imgpreload doesn’t care?
@Bob, imgpreload keeps things simple and does what you tell it to do … however if an image is already preloaded, it will be fetched form browse cache vs loading new (you should not be taxed twice for the same image url).
Hey Dimas, I just added an issue at Github. Could you please see if we can fix it? It might be a pull request but it didn’t allow me to so an issue logged.
Hey, thanks for this plugin. Its perfect! Just what I needed a callback based approach.
simple, great and lightweight. keeps its footprint down and provides excellent work.
I had my own image loader plugin(vanila js), but today I found that it was not working with IE7/8 in certain case.
googled for some ossome plugin and this works like charm.
Thank you.
Man, thanks for this. Has been really useful.
Hi all,
I’m trying to load images from a bidimensional array. Is this possible to catch the DOM object at the end of the load? Above my code:
var filesToLoad = []
filesToLoad.push({src:$(element).attr(‘background’), id:’background’})
$.imgpreload(filesToLoad,
{
each: function()
{
console.log($(this)) // big and strange object;
}
})
Thank you
Great job!
One thing I’m having problem is, when i try to replace your outcome with Images, it appears to say ‘error’ when the image actually loaded. I am trying to remove those messages and replace them with images, it just gets confusing.
Can you link us another demo, but with ACUTAL images? This will save our time and struggle.
Thank you!
Also, why does the page ‘redirect’ me to a blank page with successful loaded images (still being in the same URL)?
Thanks again!
THX.. This is working well.
Great plugin, a must-have in my collection.
If you’re having random 404 errors popping up on the console, about an image file named “undefined”, thats due to an tag that has “src” missing.
To avoid the error, add a new line right below ‘url = $(elem).attr(‘src’);’ like this: if ( ‘undefined’ == typeof url ) url = “”;
That will prevent imgpreload to try load an incorrect filename.
It seems the array of loaded images has a different order than the one of filenames you issue to the plugin (I guess the order is based on loaded status). It would be nice to have this to be the same order or have some method to fetch an image from the array of loaded images by an id or filename. Currently i’m doing something this:
var _imageCache;
$.imgpreload([‘images/test1.jpg’, ‘images/test2.jpg’], function() {
_imageCache = this;
_onImagesLoaded();
});
var _getImage = function(src) {
for(var i = 0, len = _imageCache.length; i<len; i++){
if(_getImageFilename(_imageCache[i].src) == _getImageFilename(src)) return _imageCache[i];
}
}
var _getImageFilename = function(src) {
return src.substring(src.lastIndexOf('/') + 1);
}
var _onImagesLoaded = function() {
var image = _getImage('images/test.jpg');
}
This only works in my case, where there are no duplicate filenames. It's a workaround for the fact src returns a full path instead of the given url in the array.
Is there a way to pull the percentage progress from this method? Works great for small files, but I’m concerned about larger files and people not realizing what’s happening.
I cannot download the image preload plugin..where do I go?
https://github.com/farinspace/jquery.imgpreload