views:

109

answers:

3

I have an image loaded by JS on a mouse event. It's a fairly big image so I want to make sure it gets pre-loaded. I reemmber some old techniques from years ago and found this example:

<SCRIPT LANGUAGE = JAVASCRIPT>
if (document.images) 
{
   img1 = new Image();
   img2 = new Image();
   img1.src = "imageName1.gif";
   img2.src = "imageName2.gif"
}
</SCRIPT>

I wondered if this is still good/relevant, or maybe browsers automatically detect unused images and preload them anyway? Note my page has to support IE6, so I might still need older techniques anyway, but I'm still interested if more modern browsers have a better way?

+6  A: 

Nope, this is it. Why change something that works?

But a more proper usage is like this

(function() {
   var img1 = new Image();
   var img2 = new Image();
   img1.src = "imageName1.gif";
   img2.src = "imageName2.gif"
})();

or just

new Image().src = "imageName1.gif";
new Image().src = "imageName2.gif"

Both of these avoids cluttering the global scope with variables.

And language="JavaScript" is deprecated. Use type="text/javascript".

Sean Kinsey
I tried: <script type="text/javascript">(function() {Image().src = "image1.gif";})();</script>. I now get the error under IE:"Message: Invalid procedure call or argument"
John
I had to use (new Image()).src =...
John
Yep, IE doesn't like it without `new`
Sean Kinsey
Or use `<!doctype html>`, then the script type is by default already right.
BalusC
+2  A: 

Depends what kind of images you are talking about, icons/buttons etc. could be done using a technique called CSS Sprites.

http://www.alistapart.com/articles/sprites

CharlesLeaf
Sprites are a much better option in many cases. Basically the image and its rollover are a single image used as a background, positioned differently (without repeating) based on state (normal vs hover).
Erik
+1  A: 

That's interesting. I was asking myself the exact same question recently. Another method would be to create a DOM element for each element and wait until you need to display it before injecting it into the document body. For example,

var img1 = document.createElement('img');
var img2 = document.createElement('img');
img1.setAttribute('src','imageName1.gif');
img2.setAttribute('src','imageName2.gif');

...and then later, when you know the images are ready to be inserted...

document.getElementById('imagePlaceholder1').appendChild(img1);
document.getElementById('imagePlaceholder2').appendChild(img2);

This does result in the file getting 'pre-loaded' in the modern browsers I tested and it may actually be more consistent with your own coding styles, but I'm still worried that some browsers might not load the image at the time of the element creation but wait until it's added to the document body. So I opted to use the exact solution you mentioned. At least until the next update to ECMAScript, there's nothing wrong with "old code" (at least old code like new Image()). It works and it was intended to work this way. I don't think it's particularly hacky.

[Edit] The second block of code should be made to execute when you are sure the images have loaded and/or when the user does whatever it is you expect him or her to do that triggers its appearance.

Andrew
In this case there is no guarantee that it will be loaded before being added to the DOM.
Sean Kinsey
You're right. I'll fix that. The part that's "later" should really be tied to an event, like a button-click or a scroll event (or the load event of the images themselves). If the two sections above appear in the same block, it would be no different from inserting the images in inline.
Andrew