javascriptjqueryimagepreloaderpreloading

Image preloader javascript that supports events


I am trying to find an image preloader script.

While i found a few, none of them supports an event that is triggered when preloading is finished.

Does anyone know of any script or jQuery plugin that will do this?

Hope this question is appropriate for stackoverflow - if not, feel free to remove it in an instant.


Solution

  • Here's a function that will preload images from an array and call your callback when the last one has finished:

    function preloadImages(srcs, imgs, callback) {
        var img;
        var remaining = srcs.length;
        for (var i = 0; i < srcs.length; i++) {
            img = new Image();
            img.onload = function() {
                --remaining;
                if (remaining <= 0) {
                    callback();
                }
            };
            img.src = srcs[i];
            imgs.push(img);
        }
    }
    
    // then to call it, you would use this
    var imageSrcs = ["src1", "src2", "src3", "src4"];
    var images = [];
    
    preloadImages(imageSrcs, images, myFunction);
    

    And since we're now in the age of using promises for asynchronous operations, here's a version of the above that uses promises and notifies the caller via an ES6 standard promise:

    function preloadImages(srcs) {
        function loadImage(src) {
            return new Promise(function(resolve, reject) {
                var img = new Image();
                img.onload = function() {
                    resolve(img);
                };
                img.onerror = img.onabort = function() {
                    reject(src);
                };
                img.src = src;
            });
        }
        var promises = [];
        for (var i = 0; i < srcs.length; i++) {
            promises.push(loadImage(srcs[i]));
        }
        return Promise.all(promises);
    }
    
    preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) {
        // all images are loaded now and in the array imgs
    }, function(errImg) {
        // at least one image failed to load
    });
    

    And, here's a version using 2015 jQuery promises:

    function preloadImages(srcs) {
        function loadImage(src) {
            return new $.Deferred(function(def) {
                var img = new Image();
                img.onload = function() {
                    def.resolve(img);
                };
                img.onerror = img.onabort = function() {
                    def.reject(src);
                };
                img.src = src;
            }).promise();
        }
        var promises = [];
        for (var i = 0; i < srcs.length; i++) {
            promises.push(loadImage(srcs[i]));
        }
        return $.when.apply($, promises).then(function() {
            // return results as a simple array rather than as separate arguments
            return Array.prototype.slice.call(arguments);
        });
    }
    
    preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) {
        // all images are loaded now and in the array imgs
    }, function(errImg) {
        // at least one image failed to load
    });