Preload Images Sequentially With jQuery
June 5th, 2007
Here is a small code snippet I use for preloading images for mouseovers. It uses $(window).bind(‘load’, function() {...}) to wait until all page elements have finished loading. This includes all images. If you use $(document).ready() it would start preloading images while other elements are still loading. This will make rest of the page feel slow.
Code below searches for all images with class hover. Then it adds _on to image name and pushes it to preload queue. When page has finished loading, images in preload queue get loaded. Loading happens sequentially one by one. Thus reducing stress to server.
Preloading code is based on mailing list post by Luke Lutman. Note that currently this code throws stack overflow with IE when there is more than 15 images to be preloaded. I am currently working on version which avoids this problem.
$(window).bind('load', function() {
var preload = new Array();
$(".hover").each(function() {
s = $(this).attr("src").replace(/\.(.+)$/i, "_on.$1");
preload.push(s)
});
var img = document.createElement('img');
$(img).bind('load', function() {
if(preload[0]) {
this.src = preload.shift();
}
}).trigger('load');
});
After preloading I use following code to apply mouseovers. If there is image already which ends with string _on mouseover is removed.
$(document).ready(function() {
$(".hover").each(function() {
if ($(this).attr("src").match(/_on\.(.+)$/i)) {
$(this).removeClass("hover");
}
});
$(".hover").hover(function() {
s = $(this).attr("src").replace(/\.(.+)$/i, "_on.$1");
$(this).attr("src", s);
}, function() {
s = $(this).attr("src").replace(/_on\.(.+)$/i, ".$1");
$(this).attr("src", s);
});
});
For those who want to test. You can download snippet here.
UPDATE: You might also want to check how to lazy load images

October 16th, 2007 at 02:39 AM
thanks for this. it saved me some time.
October 17th, 2007 at 01:02 PM
Glad I could help :)
October 27th, 2007 at 12:33 PM
this is great! thanks for sharing. :-)
November 15th, 2007 at 01:00 PM
hi
i tried out your example above but had some problems with images with absolute urls (which normally should be used for cache reasons)
anyway my reg exp. skills are limited so i went for the jquery irc:
pelle_: hi – does anyone have an online example of manipulating a string in jquery – more specific to insert a “_on” to the following string “http://127.0.0.1/bn_flag_english.gif” so it looks like “http://127.0.0.1/bn_flag_english_on.gif” i tried with <string>.replace(/\.(.+)$/i, “_on.$1”) seen @ http://www.appelsiini.net/~tuupola/823/sequentially-preloading-images – but this inserts the “_on” the wrong place “http://127_on.0.0.1/bn_flag_english.gif” ........ thanks for any hints
and got the following solution/suggestion:
bidioule_: .replace(/\.([^.]+)$/i,”_on.$1”)
this works for me
//
pelle
November 15th, 2007 at 08:34 PM
Good catch. Thanks!
February 15th, 2008 at 12:56 AM
thanks for sharing, i’ve modified for my needs and it works like a charm! much better than other solutions i’ve been looking at. :)
February 15th, 2008 at 12:26 PM
Thanks! This code snippet is also part of my everlasting quest on how to make websites (feel) faster.
March 5th, 2008 at 03:12 AM
How would one use a placeholder image with this? I’m trying to show a loading gif until all the images are loaded.
March 7th, 2008 at 10:24 AM
ben: Basically you would change the src attribute of original image to placeholder. Then create new image element with original src attribute. When load event of this new img element triggers you then change src of original image back to original src.
However I do not quite understand what you are trying to achieve. You usually preload images which are not visible. Is something like Lazy Loading what you are after?
January 28th, 2009 at 04:26 AM
Good work! Thank you very much! I always wanted to write in my site something like that. Can I take part of your post to my site? Of course, I will add backlink?
Sincerely, Reader
January 28th, 2009 at 12:24 PM
Timur: Sure go ahead!
February 5th, 2009 at 04:20 PM
Wouldn’t this do to preload the images?
$(window).bind('load', function() { $("img.hover").each(function() { $("<img/>").src( this.src.replace(/\.(.+)$/i, "_on.$1") ); }); });Also, you might want to do the image toggling in css instead of changing the src attribute, since that gives you the ability to add a hover class to any type of element and define its look with a style.
February 5th, 2009 at 08:01 PM
Yes it would. My example loads sequentially meaning one by one, waiting for previous preloading to finish before starting next one. This is desirable in some cases.
March 14th, 2009 at 12:53 AM
Hi there, do you have a working live example where you use this code? I don’t get it work, and i find it easiest to see it running in a website to figure what the problem is… Thanks Peter
March 15th, 2009 at 12:44 AM
Thanks, this tip was a great help to solve a problem that came to dragging my site from time. best regards fr
March 16th, 2009 at 03:02 PM
Peter: Sorry no example page at the moment. I will put it into my TODO list.
April 6th, 2009 at 04:46 PM
This is a great article, but if you just want to preload images I found this article about preloading images with jquery very detailed and useful.
Hope it will help one of you guys too.
June 26th, 2009 at 10:50 PM
Hi, here is my approach, hope it helps.
It was the only think that actually worked for me when using jquery-1.3.2 and carousel.js (http://interface.eyecon.ro/docs/carousel) that was failing in FF3 and Safari4 on both winxp and osx when the images where not fully loaded.
var imgnum = 0; var imgldd = 0; $(document).ready(function(){ imgnum = $('#carousel img').length; $('#carousel img').load(function(){ imgldd++; if(imgnum == imgldd){ $('#cargando').css('visibility', 'hidden'); $('#carousel img').css('visibility', 'visible'); $('#carousel').Carousel( { itemWidth: 160, itemHeight: 110, itemMinWidth: 160, items: 'a', reflections: 0, rotationSpeed: 1.8 } ); } }); });