Forum Moderators: open

Message Too Old, No Replies

Preload script

Automatically preload images for rollover buttons

         

rewboss

7:28 am on Aug 7, 2002 (gmt 0)

10+ Year Member



I saw the Generic JavaScript thread and wanted to post there, but it's locked. Forgive me for posting code ;) but I thought it might be useful.

This script automates the preloading of all the images you need for JavaScript rollover buttons. It can be placed in an external .js file.

For each button, you need an "on" image and an "off" image.

The images are stored using the following convention:

button_name-on.gif for the "on" image;
button_name-off.gif for the "off" image.

Here's the code:


var bNames='home products orders contact'.split(' ');
var path='/buttons/', btn=new Array();

function Button(name){
this.on=new Image();
this.on.src=path+name+'-on.gif';
this.off=new Image();
this.off.src=path+name+'-off.gif';
}

for(i=0; i<bNames.length; i++) btn[bNames[i]]=new Button(bNames[i]);

bNames is a list of all the button names (without the -on.gif and -off.gif), path contains the path to the directory you have stored the images in.

This will give you an associative array call btn which contains Button objects. Each Button has two properties, Button.on and Button.off, which are Image objects.

Thus, to access the URL of the "Home" button, you would use:

btn['home'].on.src for the highlighted image;
btn['home'].off.src for the unhighlighted image.

To demonstrate, here's what the HTML of the "Home" button might look like:


<a href="index.html" onmouseover="rollOn('home');" onmouseout="rollOff('home');">
<img src="/buttons/home-off.gif" name="home" alt="Home" /></a>

The functions rollOn and rollOff look like this:


function rollOn(name){ document[name].src=btn[name].on.src; }
function rollOff(name) { document[name].src=btn[name].off.src; }

The power of associative arrays is amazing...

tedster

6:25 pm on Aug 7, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for the script. Yes, especially when many images are involved, arrays can be a tidy solution.

I am currently keeping the generic javascript thread locked - want to keep it to scripts themselves without side conversations.

So, we'll let this thread run for a while, and then add the script once any conversation about it levels off and we can include any insights that pop up.

tedster

8:08 pm on Aug 7, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've seen a lot of array based pre-load scripts (Dreamweaver stuff in particular) that act funky on IE6. They give time delays onmouseover, showing a visible..........lag before rendering the mouseover image, even though it is in the cache.

Have you tested this one on IE6 to see if it shows that behavior?

rewboss

9:18 am on Aug 9, 2002 (gmt 0)

10+ Year Member



The Dreamweaver time............lag problem is not specific to IE6; I've seen it in IE5, too. There are two reasons for this:

1. The Dreamweaver code is horribly bloated. It contains a lot of unnecessary browser-sniffing stuff.

2. The Dreamweaver code fails to preload the images in MSIE. The first time you download a page with DW rollovers, if you keep your eye on the blinking green lights in the system tray as you mouse over a button, you can see the new image download (blink, flash, blink!). I think this is because the preload script checks for document.images, but MSIE doesn't make that array available until everything has downloaded so it skips the preload script.

highman

9:27 am on Aug 9, 2002 (gmt 0)

10+ Year Member



Great stuff! Can anyone give me the code for an external .js to preload just one big background image please.. JScript is not my strong Card ;)

rewboss

10:20 am on Aug 9, 2002 (gmt 0)

10+ Year Member



To use JS to preload any image, all you need to do is to create an Image object and then set its src property. That will automatically cause the browser to cache the image.

var myImage = new Image();
myImage.src = '/graphics/image-to-download.gif';

Rhys

12:30 pm on Aug 9, 2002 (gmt 0)

10+ Year Member



It seems counterproductive to me to put masses of script there to do this job,
I just put one of these at the foot of the page for each rollover image -
<img src="img2.gif" height=1 width=1 border=0 alt="some useful keywords can go here">
- if you put them in the order they will be required, they are there ready in cache when needed, and this won't slow down the page load, because they are loaded last.
I sometimes use this same trick to load other stuff that might be needed for later pages. Example: I preload on the preceeding page, a big 78kb pic that is offered as a panorama , so it is already in cache when needed. I do this too when thumbs are offered on a page, so that with a bit of luck, by the time the viewer has checked the thumbs, the big pics are there ready to go.

moonbiter

2:16 pm on Aug 9, 2002 (gmt 0)

10+ Year Member



I think this is because the preload script checks for document.images, but MSIE doesn't make that array available until everything has downloaded so it skips the preload script.

I wonder if this could be overcome through some creative use of the readyState [msdn.microsoft.com] property in MSIE. Hmm ...

rewboss

8:33 am on Aug 10, 2002 (gmt 0)

10+ Year Member



It seems counterproductive to me to put masses of script there to do this job,
I just put one of these at the foot of the page for each rollover image -
<img src="img2.gif" height=1 width=1 border=0 alt="some useful keywords can go here">

If you've got four or five buttons, that may well be a nifty short-cut. But after that, you lose the advantage. Compare:

var bNames='home products orders contact'.split(' ');
var path='/buttons/', btn=new Array();

function Button(name){
this.on=new Image();
this.on.src=path+name+'-on.gif';
this.off=new Image();
this.off.src=path+name+'-off.gif';
}

for(i=0; i<bNames.length; i++) btn[bNames[i]]=new Button(bNames[i]);

(289 bytes)


<img src="/buttons/home-on.gif" width="1" height="1" alt="keyword" />
<img src="/buttons/products-on.gif" width="1" height="1" alt="keyword" />
<img src="/buttons/orders-on.gif" width="1" height="1" alt="keyword" />
<img src="/buttons/contact-on.gif" width="1" height="1" alt="keyword" />

(285 bytes)

Now, your code looks more efficient -- even more so if you dispense with the alt attributes. But bear in mind that you then have to put the code on every page on your site (unless you can be certain that every visitor you get will access your site via the home page, which is often not the case); the advantage of JavaScript is that it can be put in an external file which is then cached. So, for subsequent page views, a JavaScript can be far more efficient: not just the images get cached, but also the code that caches them gets cached.

Also, the JavaScript can be further compressed by removing all unnecessary whitespace and semicolons (which is perfectly valid):


bNames='home products orders contact'.split(' '),path='/buttons/',btn=new Array()
function Button(name){this.on=new Image()
this.on.src=path+name+'-on.gif'
this.off=new Image()
this.off.src=path+name+'-off.gif'}for(i=0;i<bNames.length;i++)btn[bNames[i]]=new Button(bNames[i])

(270 bytes)

Rhys

12:23 pm on Aug 10, 2002 (gmt 0)

10+ Year Member



I'd have to agree with you rewboss,
I have now looked closely at the above script, and it is far more economical than the previous ones I saw.
In practice I don't put rollover gifs everywhere, just on the front page for effect, and I usually use the same button for all links, so it is a quick and dirty way to get a simple, fast page up. I can also use it for a pic(s) referred to by thumbs, and of course they only need to exist on one page.

Golden

5:57 am on Sep 30, 2002 (gmt 0)

10+ Year Member



Hi everyone i'm a newbie here so please help me out
rewboss with your code

var myImage = new Image();
myImage.src = '/graphics/image-to-download.gif';

my question to you is i have more than one image needed to preload how do i add more images into your code

thanks

rewboss

2:43 pm on Sep 30, 2002 (gmt 0)

10+ Year Member



Well, there are a couple of ways of doing it, depending on exactly how many images you have. If it's just two or three, just go ahead in this fashion:

image1=new Image();
image1.src='/path/to/firstimage.gif';
image2=new Image();
image2.src='/path/to/secondimage.gif';

and so on. If you have more than that, you might want to construct a simple loop and use an array to store the Image objects. The first line of the following script contains a list of all the file names separated by spaces:


var imageFileNames='/path/to/first.gif path/to/second.gif path/to/third.gif'.split(' '), images=new Array();
for(var i=0; i<imageFileNames.length; i++){
images[i]=new Image();
images[i].src=imageFileNames[i];
}

If you have all the images you want to preload in the same directory, you can make the script slightly more compact:


var imageFileNames='first.gif second.gif third.gif'.split(' '), images=new Array();
for(var i=0; i<imageFileNames.length; i++){
images[i]=new Image();
images[i].src='/path/to/'+imageFileNames[i];
}

Golden

12:29 am on Oct 1, 2002 (gmt 0)

10+ Year Member



Thanks alot rewboss