Changing Images

To create truly dynamic animations and demos you will eventually have to master the art of changing images on command.

For this lesson, I will dynamically change "imageA" into "imageB":

imageA.gif

imageB.gif

You must make sure that both images are exactly the same dimensions, otherwize when you change them, the new image will stretch itself to fit in the same area. In situations where you want to change images that are of different sizes you will not be able to use this type of code - you will have to resort to simply hiding and showing separate layers.

To start off, you have to initially show one of the images - so I decided to have a DIV tag named "imgDiv" with "imageA" inside it:

<DIV ID="imgDiv">
<IMG NAME="myImg" SRC="imageA.gif" WIDTH=75 HEIGHT=75 BORDER=0>
</DIV>

Notice that I assigned a NAME to the image (myImg), this name will be used when changing the image. The name must be totally unique, ie4. don't name the image the same as the DIV that it's inside otherwise it won't work. Usually what I do is append "Img" to the end of it as I append "Div" to the ID of a layer so that no naming conflicts occur.

Preloading Images

Before you can change the image, you have to preload the image into the browsers cache. This is the basic code to preload an image:

imagename = new Image();
imagename.src = "imagefilename.gif";

What this does is create an image object. Nothing to it really, just now we have an object by which we can access the image at any time. Whenever we need to switch an image it will already be available - you won't have to wait for the image to download because it will be cached. Since we'll be needing both imageA and imageB in the cache I have to have code to preload both of them:

imageA = new Image();
imageA.src = "imageA.gif";
imageB = new Image();
imageB.src = "imageB.gif";

The preload() Function

The more images you have to preload, the more you'll dislike having to rewrite the two lines each time. So instead of writing two lines, let's cut that down to one by using a generic preload() function:

function preload(imgObj,imgSrc) {
	if (document.images) {
		eval(imgObj+' = new Image()')
		eval(imgObj+'.src = "'+imgSrc+'"')
	}
}

where:

Examples:

preload('imageA','imageA.gif')
preload('imageB','imageB.gif')

It's best to preload your images while the page is loading rather than waiting until after the page loads, so I'd recommend always calling the preload function immediately after defining it.

Changing the Image

Once you've preloaded the images you can the access and change any image on the page. Changing images that are inside layers works a little differently between Netscape and IE so first I'll show the explicit code for changing each, then I will show a generic function that you can use in any situation.

If the image is not in a layer, the general way to change an image is this:

document.images["imageName"].src = imageObject.src

Where imageName is the name you supplied in the IMG tag, and imageObject is the name of the preloaded image object.

So in my case I could use:

document.images["myImg"].src = imageB.src

But remember, that is if the image is not in a layer, as soon as it's in a layer things change.

In Netscape, you have to reference what DIV tag it is in. In my case it's in the imgDiv layer so you have to append document.imgDiv.document in front of the code:

if (ns4) document.imgDiv.document.images["myImg"].src = imageB.src

The extra "document" between the name of the DIV and the images is necessary because Netscape treats DIV's as a totally separate document.

But in Internet Explorer you don't have to do this, you just access it as if it weren't in a layer at all:

if (ie4) document.images["myImg"].src = imageB.src

And there you have it. All you gotta do now is put that code into a separate function and call that function when you want to change it:

function changeToA() {
	if (ns4) document.imgDiv.document.images["myImg"].src = imageA.src
	if (ie4) document.images["myImg"].src = imageA.src
}

function changeToB() {
	if (ns4) document.imgDiv.document.images["myImg"].src = imageB.src
	if (ie4) document.images["myImg"].src = imageB.src
}

View images1.html for a quick example using these 2 functions.

The changeImage() Function

The changeImage() function eliminates the need to have separate functions for each time you want to change an image. You just send it the layer it is in, the name of the image, and the name of the preloaded image object - layer, imgName and imgObj respectively:

function changeImage(layer,imgName,imgObj) {
	if (document.layers && layer!=null) eval('document.'+layer+'.document.images["'+imgName+'"].src = '+imgObj+'.src');
	else document.images[imgName].src = eval(imgObj+".src");
}

In my situation, I can replace the changeToA() function with simply:

changeImage('imgDiv','myImg','imageA')

And the same for imageB:

changeImage('imgDiv','myImg','imageB')

View images2.html for an example using the changeImage() function.

Notes:

The changeImage() function can also be used for nested layers, for the layer argument you can insert parentLayer.document.childLayer similarly to how the Dynamic Layer object handles nested layers.

You can use this function for images thar aren't even in layers, just pass null for the layer argument:

changeImage(null,'myImg','imageB')

Also, the changeImage() function is backward compatible. If you have a layers page and view it in Netscape 3, the function will still work properly. You can try it out by viewing any of these examples with that browser. No other browser is capable of changing images, so if you wanted to error check for the ability to change images you can use this alteration of the changeImage() function:

function changeImage(layer,imgName,imgObj) {
	if (document.images) {
		if (document.layers && layer!=null) eval('document.'+layer+'.document.images["'+imgName+'"].src = '+imgObj+'.src')
		else document.images[imgName].src = eval(imgObj+".src")
	}
}

Both the changeImage() and preload() functions are part of the DynAPI and are in the images.js file:

Source Code

images.js

Mouse Rollovers

I figured that the topic of mouse rollovers has kinda been beaten to death so I didn't bother covering it previously. However due to the number of people that asked me about it I'll quickly show how to do it using my changeImage() function.

The idea behind rollovers is dead simple, when you put the mouse over an image, it changes to a different image, and when you move your mouse out of the image, it changes back. To accomplish this you have to surround the IMG tag with an an anchor/hyperlink and call the changeImage() function using the onMouseOver and onMouseOut events. The onMouseOver and onMouseOut events have to be called from the hyperlink because in Netscape the IMG tag does not have those events built into it.

Remember though, you have to point the anchor to somewhere before you can use it. Most often rollovers are used in toolbars so you just stick in the page you want it to go to. But in situations where you don't want the hyperlink to go anywhere, you can instead insert javascript:void(null) for the HREF. That is is just a command that does absolutely nothing. The hyperlink will still exist - it just executes a javascript command that does nothing.

<DIV ID="imgDiv">
<A HREF="javascript:void(null)"
onMouseOver="changeImage('imgDiv','myImg','imageB')"
onMouseOut="changeImage('imgDiv','myImg','imageA')">
<IMG NAME="myImg" SRC="imageA.gif" WIDTH=75 HEIGHT=75 BORDER=0></A>
</DIV>

View images3.html for a mouse rollover.

Home Next Lesson: Layer Writing
copyright 1998 Dan Steinman