New Mouseover

It does not work in Netscape 4.

On this page i give a new script for the old mouseover effect. it's much simpler than the old one, but works only in modern browsers. It makes use of advanced event handling.

The script is a test case, it's not specifically suited to use on cross–browser pages at the moment since it doesn’t work in Netscape 4 and the older browsers.

Idea

The idea is to get rid of the tag soup that old–fashioned mouseovers require. The traditional mouseover script needed:

<A HREF="whatever.html" onMouseOver="over(0)"
	onMouseOut="out(0)"><IMG
 	SRC="pix/mo_home.gif" NAME="home" etc.></A>

In contrast, this new script only needs:

<img src="pix/nr1_nrm.jpg" id="nr1" alt="image nr 1" border=0>

As you see, even the A tag is not required any more. We’re going to use modern techniques to register onmouseover and onmouseout event handlers to these image tags, entirely in JavaScript. We don’t need any more HTML attributes. In addition coding for newer browsers only allows us to get rid of the NAME attribute and use id instead.

Example

The left column contains pure IMG tags, while in the right column I put A’s around them. Since the event handler is defined on the image, not on the link, this doesn't matter.

Without links:
image nr 1
image nr 2
image nr 3
With links:
image nr 4
image nr 5
image nr 6

The script

function init()
{
	if (document.getElementById)
		var x = document.getElementById('mouseovers').getElementsByTagName('IMG');
	else if (document.all)
		var x = document.all['mouseovers'].all.tags('IMG');
	else return;
	var preloads = new Object();
	for (var i=0;i<x.length;i++)
	{
		preloads['n'+x[i].id] = new Image;
		preloads['n'+x[i].id].src = 'pix/'+ x[i].id + '_nrm.jpg';
		preloads['o'+x[i].id] = new Image;
		preloads['o'+x[i].id].src = 'pix/'+ x[i].id + '_omo.jpg';
		preloads['o'+x[i].id].onerror = function () {this.src='pix/default.gif'}
		x[i].onmouseover = function () {this.src=preloads['o'+this.id].src;}
		x[i].onmouseout = function () {this.src=preloads['n'+this.id].src;}
	}
}

Explanation

The script works as follows.

HTML

Put your images in an element with an ID, to make it more easy to register the event handlers.

<div id="mouseovers">
<img src="pix/nr1_nrm.jpg" id="nr1" alt="image nr 1" border=0>
<img src="pix/nr2_nrm.jpg" id="nr2" alt="image nr 2" border=0>
etc.
</div>

All your image tags should have an id that corresponds with the names of the images. So <img id="nr1"> has pix/nr1_nrm.jpg as normal image and pix/nr1_omo.jpg as mouseover image. The script uses the id to create the correct image names, so it’s very important that all these names correspond.

All images

onload call function init() that sets up the mouseovers. Create an array of all images in the element with ID="mouseovers", we have to register our event handlers to these images only.

function init()
{

	if (document.getElementById)
		var x = document.getElementById('mouseovers').getElementsByTagName('IMG');
	else if (document.all)
		var x = document.all['mouseovers'].all.tags('IMG');

If the browser can’t create this array it’s hopeless and we give up.

	else return;

Preload

Now create a preloads object. Its purpose is to store all images, both mouseover and normal. When we preload the images, we put them in a property of preloads with the correct name. See the Associative arrays page for an explanation of this technique.

	var preloads = new Object();

Now we go through the array with images

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

First of all we preload the normal and mouseover images and put them in preloads. See the traditional mouseover page for an explanation of preloading.

We create one property, prefixed by an n, for the normal image, and another property, prefixed by an o for the mouseover image. Thus, later on we can get the image we need by referring to the correct property of preloads. In addition, as soon as these properties are created the browser starts downloading the images, so that they’re already available when the user mouses over them.

We use the id attribute of the img tag to see which images we should load.

		preloads['n'+x[i].id] = new Image;
		preloads['n'+x[i].id].src = 'pix/'+ x[i].id + '_nrm.jpg';
		preloads['o'+x[i].id] = new Image;
		preloads['o'+x[i].id].src = 'pix/'+ x[i].id + '_omo.jpg';

For your convenience I added an onerror event handler that loads a default image if the image you requested isn’t found. This is useful for spotting missing images when creating the page.

		preloads['o'+x[i].id].onerror = function () {this.src='pix/default.gif'}

Event handlers

Now we register the actual event handlers to all images by means of the traditional event registration model. When the user mouses over the mouseover image (prefixed by o) should be shown in the correct image tag (referred to by the this keyword). onMouseOut the normal image should be restored.

		x[i].onmouseover = function () {this.src=preloads['o'+this.id].src;}
		x[i].onmouseout = function () {this.src=preloads['n'+this.id].src;}
	}
}

That’s all, the script works. No more need for huge numbers of event handling attributes cluttering up your code.

Extending the script

Traditionally mouseover effects are used on navigation links. This is because in old browsers the mouseover/out events could only be detected on links, not on any other HTML element, so you needed the links.

This modern mouseover script can work on all images in a page, if you so wish. You could even add a third event handler that makes the image behave as a link, something like:

	x[i].onclick = function () {location.href=this.id + '.html'}

Now all images are clickable, too, and function as links. The disadvantage, however, is that you lose backward compatibility. This script will only work in modern browsers, so that users of old browsers (including Netscape 4) cannot use the links any more.

Since restricting your navigation to new browsers isn’t a very good idea, it’s better not to use this technique in cross–browser pages.