(Reading: We strongly suggest you read pages 148 and 162-163 of JavaScript: A Beginner's Guide with these notes.)
We've all seen the rollover mania that grips cyberspace. It's manifested in simple, “click here” rollovers such as the ones on this homepage. Notice that as you roll over a black key on the keyboard "menu" on the left, the key is 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.)
Elementary rollover effects can be done using the CSS :hover
pseudoclass. For simple cases like text, background
colors/images, etc., that is the better way to go. But doing rollovers
with JavaScript is more powerful, and more fun!
JavaScript rollovers may seem complicated but the basic idea is actually rather simple. Typically, you have two images, such as the following (for a website 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 when the mouse rolls over the image. When that happens, your JavaScript 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 page element created by the <img> tag
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 page elements. You can write JavaScript code that runs if and when one of these events takes place. JavaScript code whose execution is triggered by an event is called an event handler.
HTML tags use certain attributes to allow you to associate your JavaScript event handler with an event associated with a particular page element:
onMouseOver
onMouseOut
onClick
As you can see, the name of the attribute corresponds to the event
that is being handled. (All attributes that specify event handlers
begin with on.) The event handler is the value of the
attribute. 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!');">
Here are some more examples of events.
In order to implement an image rollover, the event handler needs to refer
to the page element 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, which refers to the HTML object
associated with the event.
![]()
<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';">
In this example, the id is 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
(e.g., at the hyphen or the .png above).
Here are some more examples of rollovers
using other kinds of events.
You may sometimes see JavaScript code in which is written more succinctly as identifier 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 worked in
Firefox and IE, but not in Safari:
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 ( Notice that the code is not indented as nicely as we've argued that
it should be: in particular, the This link extends the previous exercise to do hyperlinks. Try to figure out how it was done, then check the code.
Why use the
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
One aesthetic disadvantage of the image link that we recommend (the
one using the To eliminate the border, you use CSS:
Of course, you should do this with some external style
sheet. You could, for example, use the following:
The This link extends the previous exercise to do borderless rollovers. Try to
figure out how it was done, then check the code.
Now that we've mastered rollovers, let's look at one interesting
variation, namely changing some text on the page along with the image.
Here it is in action:
We can also put dynamic text into the document. In this case, we
want to get the HREF of the tag that this image is inside, so we can
go up to a parent node.
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 The preloading code would typically be put in the
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 If we had several images to preload, we would use a different variable
for each one. For example:
The technique we've just described has a flaw: the images that we
will need later start loading before the ones that are
actually in the page and that we want to see. In many cases, the
images will download relatively quickly and the user won't even be
aware. But if the image files are big (which is what makes preloading
worthwhile in the first place), we don't want to load the offstage
images before the onstage ones.
What we'd really like to do is to start preloading the offstage
images as soon as the document has finished loading. (We could put
the It turns out that there is an event defined by the page
finishing loading. It's the There are even more sophisticated ways of using the onload event
handler, which we'll learn when we learn more about functions.
We can 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:
The only piece that is missing is some code to initialize the value
of
The slide-show code is organized into two pieces: there's the
initialization script that goes in the 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?
We've used the You use Only use
Events can be attached to most HTML page elements (at least in modern
browsers), and rollovers can be used to change all sorts of things.
In particular, JavaScript can access and alter all of the CSS style
properties of a page element (color, font, width, etc.). Click
here to see an example with rollover
and click events attached to table cells and a table.
Note that beyond here is information that we think you might find
interesting and useful, but which you will not be responsible for. It's
for the intellectually curious student.
An array can be thought of as a variable that has numbered slots, like
parking spaces in a pay parking lot. The number of a slot is called its
index. The numbered elements are accessed by putting the index
(or a variable containing the index) in square brackets after the variable
name. Here's an example of using an array to map numbers to filenames for
a slide show:
First, we have to initialize the array, storing the elements in their
numbered locations:
Your mental picture of the preceding code is of a big box labeled
"filenames"; this is the variable. Inside that big box is a set of three
smaller boxes all in sequence, like an egg carton; this is the array. The
three smaller boxes are labeled 0, 1 and 2; these are the slots of the
array. Inside the three smaller boxes are the strings 'lions.jpeg',
'tigers.jpeg', and 'bears.jpeg'.
Thus, we've stored three strings into the one variable called
Later, if we want a particular filename, we use the appropriate
number. For example, the following code would cause 'tigers.jpeg' to be
displayed in the alert box:
However, we don't want to use a fixed index, we want an index that
will change depending on where we are in the slide show. In this
example, the index will take on the values from 0 to 2. Imagine
there's a variable called So, to do the slide show, we start It turns out that an easy way to start over again at 0 is to use
arithmetic mod 3; that is, 0-2 are the remainders when you divide by 3, so
we can use a computation based on " These two lines of code are deceptively concise. The first line
increments the slide number, but uses the "
document.getElementById('identifier').src
.src
<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';">
Rollover Links
<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>
<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 stylesheet
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.
<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';">
<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.
Borderless Image Links
<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.
<a href = "http://www.imdb.com/title/tt0338348/"><img
style = "border-style: none"
src = "polar-green.png"
alt = "take the polar express"
onMouseOver = "this.src = 'polar-red.png';"
onMouseOut = "this.src = 'polar-green.png';"></a>
A > IMG { border: none; }
A > IMG matches an image tag immediately inside
an anchor tag. See the W3schools
CSS reference.
Implementing Simple Rollovers with Changing Text
<a href = "http://www.imdb.com/title/tt0338348/"><img
src = "polar-green.png"
alt = "take the polar express"
onMouseOver = "this.src = 'polar-red.png';
var desc = document.getElementById('description');
desc.innerHTML = 'See the IMDB page about the movie The Polar Express';"
onMouseOut = "this.src = 'polar-green.png';
var desc = document.getElementById('description');
desc.innerHTML = '';"></a>
<span style="margin-left: 30px;" id="description"></span>
<a href = "http://www.imdb.com/title/tt0338348/"><img
src = "polar-green.png"
alt = "take the polar express"
onMouseOver = "this.src = 'polar-red.png';
var desc = document.getElementById('description2');
desc.innerHTML = 'See the IMDB page '+
this.parentNode.href+
' about the movie The Polar Express';"
onMouseOut = "this.src = 'polar-green.png';
var desc = document.getElementById('description2');
desc.innerHTML = '';"></a>
<span style="margin-left: 30px;" id="description2"></span>
Preloading
<img> tags — they won't be visible
until they are needed.
head
of the document, just to get started on loading the images asap. 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>
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.
<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>
<script> element at the end of the page,
instead of in the head, but we're too likely to overlook code that's
down there.)
load event. You can use it
thus:
<body onload="var img1 = new Image(); img1.src='big_image_file.jpg'">
Slide Shows
<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';">
slideNumber. That is done by the following simple
script:
<script type = "text/JavaScript">
var slideNumber = 1;
</script>
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.
Numbering and Naming Image Files
Guernica.jpg instead of slide17.jpg
if statement:
if (slideNumber == 1) {
filename = 'lions.jpg';
} else if (slideNumber == 2) {
filename = 'tigers.jpg';
} else {
filename = 'bears.jpg';
}
the_slide.src = filename;
Caveat
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.
document.write() within the <script>
tag as part of creating the body of a web page, but an event
handler executes after the web page has been written. There's no more content
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,
document.write() within the
<script> tag, not as part of an event handler.
Rollovers Aren't Just for Images
Further Information and Examples
Arrays
<script type="text/JavaScript">
var filenames = new Array();
filenames[0] = 'lions.jpeg';
filenames[1] = 'tigers.jpeg';
filenames[2] = 'bears.jpeg';
</script>
filenames, but in numbered slots within the variable.
<script type="text/JavaScript">
alert(filenames[1]);
</script>
slideNumber. Then, the
following code will give us one of the elements of the array, as long
as slideNumber is 0, 1 or 2:
filenames[slideNumber]
slideNumber off at
0, increase it by 1 whenever the user advances the slide, and when
slideNumber exceeds 2, we start it over again at 0.
% 3":
<script type="text/JavaScript">
slideNumber = (slideNumber + 1 ) % 3;
the_slide.src = filenames[slideNumber];
</script>
% 3" to make
sure that the result is always 0, 1 or 2. The second line uses that
number as an index into the array called filenames. The
filename that was stored in that numbered slot is then made the SRC of
the image.
Summary
mouseOver event.
mouseOut event.
this variable refers to the
correct img.
img's using the
id attribute.
<a> tag.