JavaScript Image Preloader | WebReference

JavaScript Image Preloader

current pageTo page 2
[next]

JavaScript Image Preloader

One of JavaScript’s greatest strengths is the generation of HTML code on the fly, enabling all kinds of effects not possible with HTML alone. One of the hurdles to overcome when generating HTML is to ensure that any images referenced using <IMG> tags are properly loaded. This has been known to cause problems in some circumstances, especially when many <IMG> tags are added at once (even when many of them are referencing the same image). If not done properly (depending on the browser), the images might not be the correct size or load properly or even load at all.

There are a number of mechanisms used to generate HTML with JavaScript:

  • During the document load/parse phase, HTML may be written as text using document.write().
  • After the document has loaded, HTML may be added using DOM functions such as document.createElement() and Node.appendChild().
  • After the document has loaded, HTML may be inserted textually using the innerHTML property of HTML elements.

Images referenced using the first method will generally load without any difficulty as the browsers are designed to optimize the downloading of images during the document load/parse phase. All <IMG> tags that reference the same image will be grouped together so that the image is only downloaded once.

This is not true however for the other methods. While most images will load, some browsers (notably Internet Explorer) will render the images incorrectly or sometimes not at all. When <IMG> tags reference the same image they are not optimized, instead the image is downloaded for each <IMG> tag separately. This behavior gets worse as the bandwidth gets narrower. For some reason (unknown to the author), image caching doesn’t seem to affect this.

So why would anyone want to use these methods at all? There are many potential reasons:

1. Maintenance on JavaScript that has already been written this way.

2. HTML that must be added dynamically after the completion of the document load.

When preloading an image, a common mistake is to simply create an Image object and assign its “src” attribute without waiting for the image to load:

 

var myImage = new Image;

myImage.src = “images/myImage.png”;

This works if the image loads quickly enough. However if the image is used before it has loaded, this preload step will have no effect at all.

To make preloading work properly, the code must wait for the image to complete loading before it is used. In this article, I’ve created an ImagePreloader class that will preload an array of images and call a call-back function when all the images have been loaded into the browser.

The constructor for the ImagePreloader takes an array of image URLs and a call-back function as arguments.

 

function ImagePreloader(images, call-back)

{

   // store the call-back

   this.call-back = call-back;

 

   // initialize internal state.

   this.nLoaded = 0;

   this.nProcessed = 0;

   this.aImages = new Array;

 

   // record the number of images.

   this.nImages = images.length;

 

   // for each image, call preload()

   for ( var i = 0; i < images.length; i++ )

      this.preload(images[i]);

}

The call-back function is stored for later use, then each image URL is passed into the preload() method.

 

ImagePreloader.prototype.preload = function(image)

{

   // create new Image object and add to array

   var oImage = new Image;

   this.aImages.push(oImage);

  

   // set up event handlers for the Image object

   oImage.onload = ImagePreloader.prototype.onload;

   oImage.onerror = ImagePreloader.prototype.onerror;

   oImage.onabort = ImagePreloader.prototype.onabort;

  

   // assign pointer back to this.

   oImage.oImagePreloader = this;

   oImage.bLoaded = false;

  

   // assign the .src property of the Image object

   oImage.src = image;

}

The preload function creates an Image object and assigns functions for the three Image events; onload, onerror and onabort. The onload event is raised when the image has been loaded into memory, the onerror event is raised when an error occurs while loading the image and the onabort event is raised if the user cancels the load by clicking the Stop button on the browser.

A pointer to the ImagePreloader object is stored in each Image object to facilitate the call-back mechanism. An optional boolean flag can be added here to indicate whether the image loads properly or not.

Finally, the “src” attribute is assigned to start the loading of the image.

 

ImagePreloader.prototype.onComplete = function()

{

   this.nProcessed++;

   if ( this.nProcessed == this.nImages )

   {

      this.call-back(this.aImages, this.nLoaded);

   }

}

ImagePreloader.prototype.onload = function()

{

   this.bLoaded = true;

   this.oImagePreloader.nLoaded++;

   this.oImagePreloader.onComplete();

}

ImagePreloader.prototype.onerror = function()

{

   this.bError = true;

   this.oImagePreloader.onComplete();

}

ImagePreloader.prototype.onabort = function()

{

   this.bAbort = true;

   this.oImagePreloader.onComplete();

}

current pageTo page 2
[next]

Created: June 5, 2003
Revised: February 18, 2004

URL: http://webreference.com/programming/javascript/gr/column3/1