Simple and Improved Image Rollovers

Ziggy
Creative Commons License photo credit: Etwood

This programming challenge is from a Lynda.com instructional video, featuring Dori Smith, which I studied/practiced last summer but once again spring 2009. I do not mean to just re-post the wonderful Lynda.com code, but rather add instructional value to it by way of clearer variable names and explanatory comments. The end result itself is not terribly sexy, but I liked the algorithm construction process.

I post these self-instructional challenges for a few reasons. One is to demonstrate my programming learning, experience, and progression. Another reason is to make sure my code and solutions are indexed by search engines, so that other beginning programmers may get help if they need it. Finally, self-instructional challenges are interesting and different than academic challenges because I sought, discovered, and performed them on my own volition without anyone else telling me to do so. I did it because I wanted to learn and practice.

Challenge: Create a simple javascript image rollover animation. (Two arrow images colored red and blue provided in my set, but you can use any two images you like.) Do basic version first, then improve it by separating script from display code, and abstract the functions.

The Simple Method:

The HTML solution:

<html>
<head>
	<title>A Simple Rollover</title>
	<link rel="stylesheet" rev="stylesheet" href="styles.css" />
</head>
<body>
	<a href="next.html" onmouseover="document.arrow.src='images/arrow_on.gif'" onmouseout="document.arrow.src='images/arrow_off.gif'"><img src="images/arrow_off.gif" width="147" height="82" alt="arrow" name="arrow" /></a>
</body>
</html>

The CSS solution:

body {
	background-color: white;
}
img {
	border-width: 0;
}

This is a quick and dirty method, but it has problems. The biggest problem is the rollover does not execute until the user moves their mouse over the image. If the new image is large or the user’s connection is slow, there will be a noticeable delay in the first time rollover.

Another problem is that are now committed to updating JavaScript code within HTML code. This causes many efficiency hassles, such as intermingling design work with scripting work, and violating Model-View-Controller (MVC) principles.

A better method is to separate the JavaScript from the HTML page. This next improved method will attempt Don’t Repeat Yourself (DRY) principles.

The Improved Method:

The HTML solution:

<html>
<head>
	<title>An Improved Rollover</title>
	<script type="text/javascript" src="script.js"></script>
	<link rel="stylesheet" rev="stylesheet" href="styles.css" />
</head>
<body>
	<a href="next1.html">
		<img src="images/button1_off.gif" width="113" height="33" alt="button1" id="button1" />
	</a>&nbsp;&nbsp;
	<a href="next2.html">
		<img src="images/button2_off.gif" width="113" height="33" alt="button2" id="button2" />
		</a>
</body>
</html>

The CSS solution:

body {
	background-color: white;
}
img {
	border-width: 0;
}

The JavaScript solution:

// initialize the rollovers when window loads
window.onload = rolloverInit;

function rolloverInit() {
	// loop through all images on page
	for (var i = 0; i < document.images.length; i++) {
		// if current image is wrapped in an anchor tag (i.e. <a href=""><img></a>)
		if (document.images[i].parentNode.tagName == "A") {
			// initiate rollover setup for this current image, pass the current image to that function
			setupRollover(document.images[i]);
		}
	}
}

// 'thisImage' passed from rolloverInit, meaning we need to setup the rollover for this particular image
function setupRollover(thisImage) {
	// create new child image object for thisImage object's outImage property
	thisImage.outImage = new Image();
	// store current image src as the source for outimage, so it stays same when not rolled over
	thisImage.outImage.src = thisImage.src;
	// capture rollOut function as behavior when thisImage's onmouseout event handler is triggered
	thisImage.onmouseout = rollOut;

	// create new child image object for thisImage object's overImage property
	thisImage.overImage = new Image();
	// store preconsructed '_on'-state image src (using thisImage's captured id/name) as the source for overimage, so it stays changes when rolled over
	thisImage.overImage.src = "images/" + thisImage.id + "_on.gif";
	// capture rollOver function as behavior when thisImage's onmouseover event handler is triggered
	thisImage.onmouseover = rollOver;
}

function rollOut() {
	// change thisImage's src to the outImage source property (already captured)
	this.src = this.outImage.src;
}

function rollOver() {
	// change thisImage's src to the overImage source property (already captured)
	this.src = this.overImage.src;
}

And finally here is a screenshot of the improved end rollover result:

Rollover state A:

Improved rollover state A

Improved rollover state A

Rollover state B:

Improved rollover state B

Improved rollover state B

Share




Leave a Reply