A few months ago I released a jQuery plugin for preloading images. Initially, I wanted to be able to simply select image elements on the page and preload their images before showing them, however I found that generally the images that I need to preload do not exist on the page at the point where I need to preload them. I ended up not using the $.fn.preloadImages plugin at all even though it had the most functionality baked into it. To solve this, I decided to remove the $.fn.preloadImages interface leaving just the core $.preloadImages interface. I then simplified the code and implemented deferred objects to make it easy to perform events during the process of preloading images.

The core plugin still has the same parameters, however the first parameter can now be a url instead of an array since I found that to be the most common use-case.

view plain print about
1var url = "http://i622.photobucket.com/albums/tt302/Tentonaxe/WoWScrnShot_121709_231041.jpg";
2$.preloadImages(url,function(){
3    $("<img />").attr("src",url).appendTo('body');
4})

The second parameter now gets applied to the deferred object's always callback. You could also add additional methods to the deferred object just like any other deferred object.

view plain print about
1var url = "http://i622.photobucket.com/albums/tt302/Tentonaxe/WoWScrnShot_121709_231041.jpg";
2$.preloadImages(url,function(){
3    $("<img />").attr("src",url).appendTo('body');
4}).done(function(){
5    alert("Done!");
6}).fail(function(){
7    alert("Oops! Image not found!");
8})

However, just like any other deferred object, if one image fails to load, the fail callback will be immediately called and the done callback will not trigger. If you need to perform an action on each image based on done or fail, you are better off looping through the images and passing them to $.preloadImages one at a time.

The code can be found here https://github.com/tentonaxe/jQuery-preloadImages

To get the latest stable version, go to the above url and click "Tags" right next to "Downloads" on the right and download the latest version.

For easy access, below is the code for the plugin so that you can copy/paste directly from here.

view plain print about
1;(function($) {
2/*
3 * jQuery preloadImages v2.1.0
4 * http://www.tentonaxe.com/
5 *
6 * Copyright 2012 Kevin Boudloche
7 * Dual licensed under the MIT or GPL Version 2 licenses.
8 *
9 * Date: 02/24/2012
10 */

11$.preloadImages = function( imgArr, callback ) {
12    var def = $.Deferred(), imagesLoaded = 0, defArr = [];
13
14    /*
15     * This function performs a single image preload
16     */

17    function _preloadImage ( url, callback, fail ) {
18        var img = new Image();
19        img.src = url;
20        if ( img.complete || img.readyState === 4 ) {
21            callback();
22        }
23     else {
24            $( img ).bind( "error load onreadystatechange", function ( e ) {
25                //clearTimeout(errorTimer);
26                if (e.type === "error") {
27                    fail( "Image failed to load. - " + url);
28                }
29                else {
30                    callback(url);
31                }
32            });
33        }
34
35    }
36
37    /*
38     * If a callback was passed to the plugin, bind it
39     * to the always callback of the deferred
40     */

41    if ( $.type( callback ) === "function" ) {
42        def.always( callback );
43    }
44
45    /*
46     * If an empty array is passed to the plugin,
47     * immediately resolve and exit.
48     */

49    if ( $.type( imgArr ) === "array" && imgArr.length === 0 ) {
50        def.resolve();
51        return def.promise();
52    }
53
54    /*
55     * If a url is passed as the first argument,
56     * preload the url.
57     */

58    if ( typeof imgArr === "string" ) {
59        _preloadImage( imgArr, def.resolve, def.reject );
60        return def.promise();
61    }
62
63    /*
64     * One last check to make sure that imgArr is
65     * defined and is an array
66     */

67    if ( !imgArr || $.type( imgArr ) !== "array" ) {
68        def.resolve();
69        return def.promise();
70    }
71
72    /*
73     * If we've gotten this far, the first argument
74     * is more than likely an array of images. Loop
75     * through the array and preload each image. When
76     * done, resolve the deferred object.
77     */

78    $.each( imgArr, function ( i, url ) {
79
80        // add a new deferred object onto the array at this index
81        defArr[ i ] = $.Deferred();
82
83        // preload the image and resolve the deferred when done
84        _preloadImage( url, defArr[ i ].resolve, defArr[ i ].reject );
85
86    });
87
88    // When all deferreds in defArr are resolved, resolve the overall deferred object.
89    $.when.apply( $, defArr ).then( def.resolve, def.reject );
90        return def.promise();
91    };
92
93})( jQuery );