jQuery image Preloader

January 6, 2009 in jQuery Plugins

– New version with Callbacks now available –

Recently I looked into preloading images via Javascript. I found all the usual ones which require you have a list of all the images you wish to preload. For me though, specifying the images is rather annoying. Also I much prefer CSS roll overs to Javascript ones so I created this to make it easier.

This “plugin” for jQuery just allows you to preload All the images based in url enclosures within the css files attached to the current page.
I call it a “plugin” rather than a plugin as technically it doesn’t actually need jQuery at all so just remove the “jQuery.” on the function

/* jQuery.preloader - v0.9 - K Reeve aka BinaryKitten
*
* v0.9
* 	Fixed .toString being .toSteing
*
* v0.8
*		Fixed sheet.href being null error (was causing issues in FF3RC1)
*
* v0.7
*		Remade the preLoadImages from jQuery to DOM
*
* v0.6
* 		Fixed IE6 Compatability!
*		Moved from jQuery to DOM
*
* v0.5
* 		Shifted the additionalimages loader in the preLoadAllImages so it wasn't called multiple times
* 		Created secondary .preLoadImages to handle additionalimages and so it can be called on itself
*/
jQuery.preLoadImages = function(imagesList) {
	var pic = new Array();
	if (typeof imageList != 'undefined') {
		if (imageList.constructor.toString().indexOf('Array') != -1) {
			var l = imageList.length;
			for(apicsIdx=0;apicsIdx<l;apicsIdx++) {
				var c = pic.length;
				pic[c] = new Image();
				pic[c].src = imageList[apicsIdx];
			};
		}
		else {
			var c = pic.length;
			pic[c] = new Image();
			pic[c].src = imageList;
		}
	}
	pic = undefined;
}
jQuery.preLoadAllImages =  function(additionalimages) {
	var regex = new RegExp("url\((.*)\) ",'i');
	var pic = new Array();
	var l = document.styleSheets.length;
	for (sheetIdx=0;sheetIdx < l;sheetIdx++){
	var sheet = document.styleSheets[sheetIdx];
	if (typeof sheet.href == 'string' &amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp; sheet.href.length > 0) {
		var spl = sheet.href.split('/');
		var filename = spl.pop();
		var path = spl.join('/')+'/';
	}
	else {
		var path = './';
	}
	myRules = sheet.cssRules ? sheet.cssRules : sheet.rules;
	for (ruleIdx=0;ruleIdx<myRules.length;ruleIdx++) {
		var Rule = myRules[ruleIdx];
		txt = Rule.cssText ? Rule.cssText : Rule.style.cssText
		var match = regex.exec(Rule.cssText);
		if (match != null) {
			if ( match[1].substring(0,1) == '/') {
				var pic2Load = match[1];
			}
		else {
			var pic2Load = path+match[1];
		}
		if (typeof console != 'undefined')
			if (typeof console.log != 'undefined')
				console.log(pic2Load);
				var c = pic.length;
				pic[c] = new Image();
				pic[c].src = pic2Load;
			}
		};
		sheet = undefined;
		match = undefined;
		styleList = undefined;
		Rule = undefined;
	}
	if (typeof additionalimages != 'undefined') {
		if (additionalimages.constructor.toString().indexOf('Array') != -1) {
			var l = additionalimages.length;
			for(apicsIdx=0;apicsIdx<l;apicsIdx++) {
				var c = pic.length;
				pic[c] = new Image();
				pic[c].src = additionalimages[apicsIdx];
			};
		}
		else {
			var c = pic.length;
			pic[c] = new Image();
			pic[c].src = additionalimages;
		}
	}
	regex = undefined;
	pic = undefined;
};

Thanks to Roberto for pointing this out, I forgot to add how to use it and what it does..

What it does:
Basically the $.preLoadAllImages() function cycles through all your style sheets looking for background images and creates an array that will handle them. After this is done, it cycles through this array and creates a cached image for each file.
If you passthrough an array or filname to the function it will preload those/that image(s) as well.

Finally the $.preLoadImages just preloads images passed to it.. be it a single item or an array of items.

Usage
This really is the simple part.

  1. copy the code above to a new file.. save it as jquery.Preloader.js
  2. make sure you know the relative filepath to this new js file
  3. add jquery to the list of included files by doing
  4. add the new js file to the page:
  5. Finally call the function you want.. you don’t have to use jquery’s document ready, as really you might want to have the images ready before hand.. but that’s down to you.. just call $.preLoadAllImages(); and Voila!