Posted
5 October 2009 @ 9am

Tagged
, , , ,

Share and Enjoy
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Digg
  • Twitter
  • Reddit
  • MySpace
  • Technorati
  • StumbleUpon
  • Tumblr
  • Slashdot
  • email
  • Print

prototype-based image preloader

Preloading images is often a final optimization step when writing a javascript heavy web app. I think its generally because its seen as a pita, so it keep getting pushed as the site is developed until you get to the very end, and something has to be re-engineered to make it look right. I think that’s a shame, because a simple preloader is pretty easy to write and use and can really improve the look & feel of a website. Here’s mine:

var Preloader = {
    load: function() {
        var args = $A(arguments);
        var callback = Object.isFunction(args.last()) ? args.pop() : Prototype.emptyFunction;
        var urls = Object.isArray(args[0]) ? $A(args[0]) : args;
        var loaded = 0;
        var images = $A();

        var onload = function() {
            if (++loaded == urls.length) {
                callback();

                // cleanup
                images.each(function(i) { delete i });
                images = callback = urls = null;
            }
        };

        urls.each(function(url) {
            var image = new Image();
            image.onload = image.onerror = onload;
            image.src = url;
            images.push(image);
        });
    }
};

To use you load it up with url’s like:

// to load a single image
Preloader.load('http://futureadapter.com/wp-content/uploads/2008/08/fa_blog3-1.jpg');

// to load a bunch of images
Preloader.load('http://futureadapter.com/wp-content/uploads/2008/08/fa_blog3-1.jpg', 'http://futureadapter.com/another_image.jpg');

// or, alternately, if it works better for loading a bunch of images
Preloader.load(['http://futureadapter.com/wp-content/uploads/2008/08/fa_blog3-1.jpg', 'http://futureadapter.com/another_image.jpg']);

And the final argument can be a callback which executes after all the images have been loaded.  You’d commonly use this for something like:

// show an ajax spinner in your front end over the updating area
$('target').startWaiting();

new Ajax.Request('/images', {
    method: 'get',
    onSuccess: function(response) {
        // grab the image data from the back end
        var images = response.responseJSON['images'];
        var urls = images.invoke('public_filename');

        // load up the images
        Preloader.load(urls, function() {
            // when all the images have been loaded, replace the
            // existing ones with the new page (for instance)
            $$('#target .image').each(function(image, index) {
                image.writeAttribute('src', urls[index]);
            });

            // and reveal the updated area with the new images
            $('target').stopWaiting();
        });
    }
});

Have fun!


blog comments powered by Disqus
counter_cache as an optimization step authlogic plugin error/fix