Reading: Thau Chapter 4 to page 61.
We've all seen the rollover mania that grips cyberspace. It's manifested in simple, “click here” rollovers such as the ones at the Music Department. Notice that as you roll over the menu on the left, the links get highlighted. There are also more elaborate double rollovers such as the ones at the Quantitative Reasoning Program. Not only are the links changing color, but some explanatory text appears on the right. (The rollovers on the Wellesley College home page are different and much more complex. We will not discuss them in this course.)
Rollovers may seem complicated but they are actually rather simple. Typically, you have two images, such as the following (for a web site booking tickets to the north pole):
to be
displayed by default
to be
displayed when the mouse rolls over the image
You display the default image as usual and the browser watches the mouse's position. You ask the browser to execute some JavaScript (JS) when the mouse rolls over the image. When that happens, your JS code swaps images (in this case from the image with the green background to the one with the red background).
To understand this in more detail, we have to distinguish among:
IMG tag, which does several things:
SRC attribute into the object.
In a sense, the IMG tag creates an image object which
functions like a picture frame. A rollover replaces the contents of
the picture frame with another picture.
An event is some action that takes place. A browser can detect some events that might be of interest to the author of a web page. For example, the browser can determine when a user:
There are common JavaScript events defined on most HTML tags. We will see and use some of those events later in this course. When these events take place, they trigger a JavaScript event. The programmer (that would be you) has the option of telling Javascript what to do when an event arises by writing event handlers using attributes such as:
onMouseOver
onMouseOut
onClick
An event handler is some JavaScript code that is the value of one of several special tag attributes, like the ones named above. As you can see, the name of the attribute corresponds to the event that is being handled. When that event occurs, the JavaScript code in the event handler is executed. Here's an example that just does a simple alert:
![]()
<IMG SRC="polar-green.png" ALT="take the polar express" onClick="alert('thanks for clicking!');">
In order to implement a rollover, the event handler needs to refer to the tag that will have its image data modified. Usually, of course, that image is the same one that has the event-handler attribute, but not always (as we will see). In that special case, we can use a special JavaScript variable named this.
![]()
<IMG SRC = "polar-green.png" ALT = "house icon" onMouseOver = "this.src = 'polar-red.png';" onMouseOut = "this.src = 'polar-green.png';">
Let's talk about the code in the onMouseOver event
handler. It's traditional to use the up-and-down
capitalization for that and similar event handlers, since it's easier to
see the words it comprises. However, as you know, HTML is not
case-sensitive, so you can specify the name of the attribute in all-lower
or all-upper case.
The value of the attribute is all the stuff enclosed by double quotes,
and the value of the attribute is automatically treated as JavaScript code,
without having to specify SCRIPT tags.
In this case, the JavaScript code is an assignment statement that
changes the value of this.src. The this
variable may seem magical: its value automatically changes from place
to place and it always means “the current object.” In this
instance, it means the image object created by the IMG
tag that contains the event handler code; it's as if the
SRC attribute of the tag is changing. As you know, the
SRC attribute determines which image file is displayed,
so changing the SRC attribute causes a new image to be
downloaded and shown.
The other event handler is almost identical. It re-loads the original image data when the mouse is no longer over the image.
In JavaScript, as in English, the word “this” depends
on context. In the example above, this means the
JavaScript image object created by the IMG tag. To do
more complex rollovers, we'll have to be able to refer to them.
However, we can't just say “that” because the browser
should respond “which?”
To refer to any image other than this one, we have to
give it a name or an identifier. To do that, we can
use the id attribute. (Some old code still uses the
name attribute, but name has been deprecated
and id is preferred. You can use id to
label pretty much any HTML tag.)
Let's start with using id for just a simple rollover.
The following code is equivalent to the rollover in the previous
section:
![]()
<IMG SRC = "polar-green.png" ID = "pic1" ALT = "house icon" onMouseOver = "document.getElementById('pic1').src='polar-red.png';" onMouseOut = "document.getElementById('pic1').src='polar-green.png';">
Notice that the id is just pic1, which is
fine for this example, but in general it's better to label the image
in a way that is meaningful to you as the web author, so that you can
remember what role the image plays. For example, label it
infobox or caption or whatever.
Now, if we want some other image to change when we roll
over this one, all we need to do is use id to label the
one we want and use the label in our JavaScript code. Here's an
example:
![]()
![]()
<IMG SRC = "polar-green.png" ID = "picleft" ALT = "take the polar express" onMouseOver = "document.getElementById('picright').src = 'polar-red.png';" onMouseOut = "document.getElementById('picright').src = 'polar-green.png';"> <IMG SRC = "polar-green.png" ID = "picright" ALT = "take the polar express" onMouseOver = "document.getElementById('picleft').src = 'polar-red.png';" onMouseOut = "document.getElementById('picleft').src = 'polar-green.png';">
To do a double rollover, you just have to change the
SRC of more than one IMG. For example:
![]()
![]()
<IMG SRC = "polar-green.png" ID = "left2" ALT = "take the polar express" onMouseOver = "document.getElementById('left2').src = 'polar-red.png'; document.getElementById('right2').src = 'polar-red.png';" onMouseOut = "document.getElementById('left2').src = 'polar-green.png'; document.getElementById('right2').src = 'polar-green.png';"> <IMG SRC = "polar-green.png" ID = "right2" ALT = "take the polar express" onMouseOver = "document.getElementById('left2').src = 'polar-red.png'; document.getElementById('right2').src = 'polar-red.png';" onMouseOut = "document.getElementById('left2').src = 'polar-green.png'; document.getElementById('right2').src = 'polar-green.png';">
Notice that the code in the event handler can get rather long.
There are many ways to abbreviate the code, which we will learn when
we get to functions, but even without that, length is not a problem.
The browser doesn't care how long a line is, so you could just let it
stretch, even to a hundred characters or so. Long lines, however, are
difficult for people to read, so putting in line breaks is a good
idea. The browser doesn't object to line breaks within an event
handler (as illustrated above). Typically, you would break the line
at a logical location within the JavaScript code, such as after the
semi-colon. The only restriction is you must not break the line within a
JavaScript string literal, such as within either of the filenames
(eg, at the hyphen or the .png above).
You may sometimes see JavaScript code in which
document.getElementById('identifier').src
is written more succinctly as
identifier.src
Unfortunately, while this works in many browsers, it does not work in all browsers. For this reason, we recommend that you do not use this abbreviation. For example, in Spring, 2008, the following works in Firefox and IE, but not in Safari:
![]()
![]()
<IMG SRC = "polar-green.png" ID = "left3" ALT = "take the polar express" onMouseOver = "left3.src = 'polar-red.png'; right3.src = 'polar-red.png';" onMouseOut = "left3.src = 'polar-green.png'; right3.src = 'polar-green.png';"> <IMG SRC = "polar-green.png" ID = "right3" ALT = "take the polar express" onMouseOver = "left3.src = 'polar-red.png'; right3.src = 'polar-red.png';" onMouseOut = "left3.src = 'polar-green.png'; right3.src = 'polar-green.png';">
This link has a nice example of image swap behavior. Try to figure out how it was done, then check the code.
The rollovers above swap images very nicely, but they're not active links, which is the most common use of a rollover. A rollover link is nice because the user gets visual feedback that the mouse is positioned correctly before they click.
To make an image into a hyperlink, all you need to do is wrap it with
the anchor (A) tag:
<A HREF = "http://www.imdb.com/title/tt0338348/"><IMG
SRC = "polar-green.png"
ALT ="take the polar express"
onMouseOver = "this.src='polar-red.png';"
onMouseOut = "this.src='polar-green.png';"></A>
Notice that the code is not indented as nicely as we've argued that
it should be: in particular, the IMG tag is at the end of
a line, instead of being neatly indented under the A tag.
In this case, aesthetics has to give way to function, because if we
indent the IMG tag below the A tag, the line
break will end up causing blue-underlined whitespace in the browser,
which will look ugly. Whenever you are using the A tag,
remember that everything between the start tag and the end
tag will end up with blue underlining (or whatever your style sheet
specifies), and so you have to be careful, even with
“invisible” stuff like spaces and line breaks. It is
always safe, however, to break lines between attributes of a tag, as
we did between IMG tag and its SRC
attribute.
This link extends the previous exercise to do hyperlinks. Try to figure out how it was done, then check the code.
Why use the A tag at all? Why not have a JavaScript
event handler that responds to a mouse click by changing the browser's
location to the desired page? The code would look like the following:
![]()
<IMG SRC = "polar-green.png" ALT = "take the polar express" onClick = "window.location = 'http://www.imdb.com/title/tt0338348/';" onMouseOver = "this.src = 'polar-red.png';" onMouseOut = "this.src = 'polar-green.png';">
There is a certain aesthetic beauty to code like this, at least to
computer scientists, because of its simplicity. However, we should
eschew this simplicity and prefer the more complex code that uses the
A tag. The reason is that some older browsers don't
support event handlers or JavaScript, and some users disable
JavaScript in their preferences, or are using screen-reading software
that doesn't handle these events in the same way. In short, if the
JavaScript doesn't work, for any reason, you still want your web page
to work. This is what is known as graceful degradation.
One aesthetic disadvantage of the image link that we recommend (the
one using the A tag) is the blue border that some
browsers will display. The blue used in links is a strong hint to the
user that something is a link, so the blue border is generally a good
thing unless you're quite certain that your user understands that this
image is a link. But, in many cases, you are certain that is so (for
example, navigation bars make the intention clear), and you want to
get rid of the blue border.
To eliminate the the border, you use CSS:
<A HREF = "http://www.imdb.com/title/tt0338348/"><IMG
STYLE = "border: none"
SRC = "polar-green.png"
ALT = "take the polar express"
onMouseOver = "this.src = 'polar-red.png';"
onMouseOut = "this.src = 'polar-green.png';"></A>
This link extends the previous exercise to do borderless rollovers . Try to figure out how it was done, then check the code.
One problem that can arise with rollovers is that when the mouse rolls over the image for the first time, the second image has to be downloaded across the network, and that can cause a noticeable delay. When that happens, the users don't get the visual feedback they expect, and confusion can ensue, or at least annoyance.
Browsers automatically cache anything they download. “To cache” (pronounced “cash”) means to keep a copy in memory or on the local disk. The browser cache makes references to previously loaded images pretty fast. Thus, the solution is to make sure that the second image is downloaded before it is needed. This is called preloading.
We do this by downloading rollover images when the page loads, but
we keep them in “offstage” (undisplayed) objects, rather
than in IMG tags — they won't be visible until they
are needed. The preloading code would be put in the HEAD
of the document, to make sure it has occurred before any possible
rollover. If we wanted to preload the red Polar Express image, we
could do the following:
<script type="text/JavaScript">
var polar_red = new Image();
polar_red.src = "polar-red.png";
</script>
Here's what's going on. The first line of code creates an object
to hold image data. This is an Image object, not surprisingly. The
object is placed in a variable called polar_red. It's
not important what we name the variable; we could have called it
picture or just p. The second line of code
assigns a URL to the SRC attribute of the object, thereby
loading the image data across the network and into the object. At
this point, the image data is cached and any uses of the
polar-red.png file will load very quickly.
If we had several images to preload, we would use a different variable for each one. For example:
<script type="text/JavaScript">
var nav1 = new Image();
nav1.src = "home-button-over.png";
var nav2 = new Image();
nav2.src = "history-over.png";
var nav3 = new Image();
nav3.src = "eboard-over.png";
...
</script>
You could use extend the rollover idea to a slide show. Each time you click on the following image, the image changes. It cycles through six possibilities.
Almost all the work is done in the event handler, which increments the slide number, using the remainder operator (the percent sign) to start over again when we reach 6. The code is as follows:
<IMG ID = "the_slide"
SRC = "../../Images/die1.gif"
HEIGHT = "70"
WIDTH = "70"
onClick = "slideNumber = (slideNumber%6) + 1;
document.getElementById('the_slide').src
= '../../Images/die' + slideNumber + '.gif';">
The only piece that is missing is some code to initialize the value
of slideNumber. That is done by the following simple
SCRIPT:
<script type="text/JavaScript"> var slideNumber = 1; </script>
The slide-show code is organized into two pieces: there's the
initialization script that goes in the BODY of the page,
and the event handler that advances the slide. Note that we
don't put the line of code that initializes the
slideNumber variable in the event handler. Why not?
Because if we did so, the slide number would start over at one every
time we clicked on the image, and so we would only see the first
slide.
Note that it's not important that you click on the image to advance the slide show. You could also have a button to do that.
One trick that helped the dice slide show was that the names of the image files had a number in them, so we could mathematically generate a number and thereby generate a filename. What can you do if your image files don't have that convenient pattern?
Guernica.jpeg instead of slide17.jpeg
if structure:
<script type="text/JavaScript">
if (slideNumber == 1) {
filename = 'lions.jpeg';
} else if (slideNumber == 2) {
filename = 'tigers.jpeg';
} else {
filename = 'bears.jpeg';
}
the_slide.src = filename;
</script>
We've used the alert() function in some of our examples
because it's obvious when it runs. You can use alert()
anywhere in your JavaScript code. However, you can't use
document.write() in an event handler. Why? Not because of
any rule in JavaScript, but because it doesn't make sense.
You use document.write() within the SCRIPT
tag as part of creating the BODY of a web page, but an event
handler executes after the web has been written. There's no more
left to write, so the document.write() either has no effect
or causes the browser to hang, thinking that you're writing a new web
page. So, remember,
Only use
document.write()within theSCRIPTtag, not as part of an event handler.
mouseOver event.
mouseOut event.
this variable refers to the
correct IMG.
IMGs using the
ID attribute.
A tag.
Optional reading: Thau Chapter 4.
© Computer Science 110 Staff
This work is licensed under a Creative Commons License
Date Modified:
Sunday, 16-Mar-2008 17:50:17 EDT