


|

Helen Bradley and John
Hilvert continue our exploration of JavaScript and look at controlling graphics to create
some great effects, including menus which change as the mouse moves over them.
|
|
We've provided all the files you need for this project
on this month's (April '98) cover CD-ROM. You can load example*.htm (*depending on which example you wish to
use) into your browser by simply clicking the appropriate link. If you have more than one
browser on your computer, open it in the others and notice how the page which appears
changes according to the browser and version you're using.
To view or use the source code for each file,
you can use any HTML editor, text editor and most Web browsers.
The HTML source in this project has been
written so that you can use it for a number of applications. It displays one of a range of
three pages depending on what browser your user is using, and is easily expandable beyond
this. The source has been designed so that you can easily adapt it to your own programs.
|
Browser compatibility
The source code examples in this tutorial work fine with Netscape 3 and higher and
Internet Explorer 4 but won't work in Internet Explorer 3.0. If you have IE3, you'll find
that the routines don't crash the program, it just doesn't support the features used here
-- a good example of a program 'degrading gracefully'.A sensible approach to take is to team this menu with the browser checker
from last month's column and send users with a JavaScript browser to your enhanced page
containing this month's menu and leave other users on the browser checking page with a
plainer, non-JavaScript menu.
|
Example
1
The first example is shown in Figure 1d. It's a simple form button on a Web page that,
when pushed, changes the graphic to a second image. The source for this is in Source Box #1. In this example we've used the routine to run an
animated GIF file. There's a static image of a flag flying the PC User logo on the page
when it loads, and when the button is pressed, a second image (an animated GIF file) is
loaded which shows the flag flying on the page.While
you can use this example to run an animated GIF you can also use it to change between two
static graphics. For example, if you have a picture of a closed book and an open one, you
can put the image of the closed book on the page and set the button to 'open' the book
when it is clicked.
To create this example, and all the others in this column,
type the source from the HTML Source box into an HTML editor or text editor such as
Windows Write and save it as an HTM file. Remember to type the source exactly as shown and
pay particular attention to the capitalisation of the JavaScript code, otherwise you run
the risk of encountering errors.
Copy the images referred to in the HTML source from the
CD-ROM into the same directory as you've saved your HTM file and then load the file into
your browser using File, Open. To see how this example1.htm works, simply click on the
button to run the PC User flag animation. This will only work once, so you'll need to
reload the page if you want to click the button again.
The source for this example is simply a standard image tag
with one difference – it contains a NAME attribute.
<IMG SRC="pcuflag1.gif"
NAME="pcuflag" HEIGHT="32" WIDTH="32"
ALT="pcuflag1.gif">
Every image on a page is an element in an image array called
'images'. The first image has the index 0 (images[0]) and the second one index 1
(images[1]), etc. Accessing images using the image array is possible, you just keep track
of which image is in which array element. However, it's easier to name each image that you
want to manipulate and use its name instead of its array index. This is what we have done
here, we have named the image on the example1.htm page and called it "pcuflag".
When it is named you can address the image in one of two ways:
document.pcuflag
or
document.images["pcuflag"]
You can name your images with any valid name -- to be safe,
use alphabetical characters and the underscore and no spaces. When an image is named you
can replace the graphic in that image location with another graphic provided both images
have the same height and width, ie, they have the same physical dimensions. This command
replaces the image named "pcuflag" with the image "pcuflag2.gif":
document.pcuflag.src = "pcuflag2.gif"
This is exactly what will happen if the user clicks on the button on the form; the onClick
event handler will run the JavaScript code to change the image in the location called
"pcuflag".
This is the source that creates the button on the Web page,
which is a button object on a form, and which contains the code to be run when the user
clicks the button:
<FORM>
<INPUT TYPE=button VALUE="Unfurl flag"
onClick="document.pcuflag.src='pcuflag2.gif'">
</form>
The button object's value property is the text that appears
on the button face.
|

Figure 1d: When the user clicks the button on this page the
graphic will change, but it cannot be changed back without refreshing the page. |
Example
2
The second example is an image rollover. When your mouse is positioned over the image a
second image is loaded and when the mouse is taken away, the original image is restored.
The source for this is in Source Box #2.The source to run this is very simple but your user will have to wait while
the second image is loaded and because of the slight delay they may not understand that
the image will change if they position their mouse over it.
The work on this page is done by the link tag which will
respond to the mouse being moved over it. The onMouseOver is an event handler which
executes JavaScript when the mouse is moved over a link. This is different to clicking the
link in that it involves simply moving the mouse pointer over the image so it is poised
over it. The onMouseOut event handler is called when the user moves the mouse pointer away
from a link.
Because the onMouseOver and onMouseOut event handlers are
associated with a link there is a 'dummy' link used in this example so that your user
won't go anywhere if they click the image. They can simply stop and start the tickertape
by moving their mouse over the image and then moving it away again.
This source loads the animated image ticker2.gif when the
mouse is over the image and, when the mouse is moved away, it loads the original image
again:
<A HREF="#" onMouseOver=
"document.tickertape.src='ticker2.gif'"
onMouseOut = "document.tickertape.src='ticker1.gif'">
<IMG SRC="ticker1.gif" NAME="tickertape" HEIGHT="17"
WIDTH= "113" ALT="Run the tickertape animation"></A>
In this example, like the last, a static image is displayed
on the page when it loads and, when the user's mouse is placed over it, an animated GIF is
loaded and run. Again, you don't have to use an animated GIF -- you could use a second
static image, an embedded sound or even write a routine to change the status bar text when
the mouse pointer moves over the graphic.
|

Figure 2d: This sample page runs an animated GIF file when the
mouse is over the graphic but the user will have to wait while the image loads.
|
Example
3
The sample page in example3.htm is the previous example this time rewritten with the
second image preloaded on the page. The source for this is in Source
Box #3. When the page is loaded the JavaScript code creates two new image objects
using the Image() constructor and loads them with images from the server. This code creates a new image object animatedLogoOn and animatedLogoOff and
loads them with the animated image logoani2.gif and the static image logoani1.gif:
animatedLogoOn = new Image();
animatedLogoOn.src = "logoani2.gif";
animatedLogoOff = new Image();
animatedLogoOff.src = "logoani1.gif";
The code only loads the images and doesn't actually display
them. The first image logoani1.gif is loaded on the screen in the BODY of the document by
this HTML source:
<A HREF="#" onMouseOver=
"animationOn()"
onMouseOut = "animationOff()">
<IMG SRC="logoani1.gif" NAME = "animation" HEIGHT="40"
WIDTH="134" BORDER = 0 ALT="Animated PC User logo"><BR>
When the user moves their mouse over the image the
onMouseOver event handler calls the function animationOn which loads the image stored in
animatedLogoOn -- the animated GIF file. When the mouse is moved away from the image the
onMouseOut event handler calls the function animationOff() which loads the image in
animatedLogoOff which is the original static image.
Again, animated images have been used simply for effect but
the routine works just as well with static images, too. Because the images are loaded when
the page is loaded the change from one image to the other happens more quickly than if the
browser has to call the server to load the file, as it did in the previous example.
|

Figure 3d: This sample page includes a JavaScript routine to
preload the two images so that the animation runs as soon as the mouse moves over the
image. |
Example
4
The fourth example is a menu created from a series of images made from fancy text saved as
JPG files which together form a menu to allow a user to navigate a Web site. The source
for this is in Source Box #4.The images are loaded into individual cells in a one-row by five-column
table. When the user points their mouse to an image, a second image similar to the first
but a different colour, replaces the first (see Figure 4d). The user sees that the browser
has responded to the change in mouse position and understands that the option being
pointed to will be selected if they click their mouse.
Instead of a 'dummy' link, each of the images is linked to
another Web page which the user will be taken to if they click their mouse on that link.
The images are simple text buttons created in Paint Shop Pro (see January '98, 'HTML
tips', page 58, for instructions on how to create them). The 'Home' button was created in
white and again in blue and each image was saved as a JPG file, the blue button in
img0on.jpg and the white button in img0off.jpg. Each of the other buttons was created and
saved the same way as an on/off pair and the same size -- the only difference being in the
text colour.
The code that runs the menu is an extension of the code in
Example 2 and suffers from the same problems of delay in that the user must wait for the
browser to load the 'on' image from the server before they'll see the button change.
To test this menu you'll need to create five additional HTML
files called home.htm, back.htm, next.htm, photos.htm and contact.htm. They need only have
a single line of text in them and be saved using these names, so when you click the link,
you will actually move to the named file, not get an error. This is the sample source for
the file home.htm and you can create the others by altering the text and repeatedly using
File, Save As to save it under the other names:
<HTML>
<HEAD>
<TITLE>Home Page</TITLE>
</HEAD>
<BODY>
This is the home page.
</BODY>
</HTML>
|
Figure 4d: The options on this menu change colour
as the user's mouse moves over them. |
Example
5
The fifth example is the completed menu. The images are loaded at the same time that the
page is loaded and a single function turns the image on or off when the user moves their
mouse. The source for this is in Source Box #5.The page requires the same series of on/off image pairs as example 4. The
file img0on.jpg should contain the image the user will see when the mouse is over the menu
option and img0off.jpg should contain the image the user will see when the mouse is not
poised over the menu option. You can adapt this code to extend to 10 on/off image pairs
which should be numbered 0-9.
The JavaScript variable buttonCount contains the number of
buttons that are used on the page; in this case there are five buttons numbered img0on.jpg
to img4on.jpg and img0off.jpg to img4off.jpg.
There are two arrays: one which contains the 'on' buttons
called buttonOn and one which contains the 'off' buttons called buttonOff. Each of these
arrays are created to hold five elements with these lines of code:
buttonOn = new Array(buttonCount);
buttonOff = new Array(buttonCount);
The array elements are then initialised and filled with the
image objects from the server by a loop which executes 'buttonCount times', in this case
five times. On each pass through the loop, an array element is defined as new image
object. The code then creates an 'on' image name using the current loop index and some
string concatenation, and it then loads the image into the image object. This is then
repeated for the 'off' image.
By the time the loop has fully executed all the required
images (in this case 10 images representing five on/off button pairs) are loaded into the
browser, but not displayed. This is the loop that loads the images:
for (i = 0; i < buttonCount; i++) {
buttonOn[i]= new Image();
imageName = 'img' + i + 'on.jpg';
buttonOn[i].src = imageName;
buttonOff[i] = new Image();
imageName = 'img' + i + 'off.jpg';
buttonOff[i].src = imageName;
}
The body of the document is a table menu structure similar to
that in Example 4. Each table cell displays one of the five button 'off' images. This is
the HTML source for the first (home) button:
<TD><A HREF="home.htm"
onMouseOver="buttonSelect('img0','off')"
onMouseOut="buttonSelect('img0','on')">
<IMG SRC="img0off.jpg" NAME= "img0" BORDER = 0
HEIGHT="26" WIDTH="66" ALT="Home
Page"></A></TD>
When the user's mouse pointer is moved over an image, the
function buttonSelect is called with two arguments; the first is the Name of the image
(the same as is given to it by the NAME attribute in its IMG tag), and the second is the
current state of the button (on or off).
The buttonSelect function tests to see if the buttonstate
parameter is 'on' and if it is it displays the 'off' button. If the state is not 'on',
(ie, it is 'off') then the 'on' button is displayed. To determine which image from the
array to display the function strips the fourth character from the image name which was
passed to it in the calling statement. The method charAt(3) returns the fourth character
of a string (the characters are numbered from 0 being the left-most character). For the
first button the name 'img0' is passed to the function and, when the charAt(3) method is
used it returns the result 0 which is then used to display either the image stored in the
array element buttonOff[0].src or buttonOn[0].src. This is the function which displays the
required button:
function buttonSelect(buttonName,buttonState) {
if( buttonState == 'on')
document.images[buttonName].src = buttonOff[buttonName.charAt(3)].src;
else
document.images[buttonName].src = buttonOn[buttonName.charAt(3)].src;
}
|
Customise it
You can customise the menu in Example 5 by adding up to five more buttons. You'll need an
'on' and 'off' image for each button and you'll need to change the buttonCount variable to
the number of buttons you have. That's the only change you need make to the JavaScript
itself. In the BODY of your document you'll need a link and image anchor for each button.
You can create these quite easily by adapting the link and anchor source for the other
buttons already in the menu. For the link you'll change the name of the HTM file to link
to and change the arguments in the two buttonSelect function calls. In the IMG tag change
the JPG filename, the image name, its height and width and the Alt text. If you prefer to use GIF files instead of JPG files, you can by simply
changing the extension everywhere it appears in the source. If you're using JPG files,
remember that they do not support transparency and you should ensure that the background
of your images blend well with the background page colour.
To make sure your pages are compatible with a range of
browsers, team this source code with the browser checker from last month's column so that
you send users with a JavaScript browser to the page containing your enhanced graphical
menu and leave other users on the original browser checking page with a plainer,
non-JavaScript menu.
|
Web resources
Books
- For beginners
JavaScript Interactive Course, Waite Group Press
- For more accomplished users
Creating Killer Interactive Web Sites, by Sather, Ibanez, DeChant & Pascal, Hayden
Books.
Next month
In next month's column we continue exploring JavaScript by using it to
manage a site which uses frames and we look at tips and traps for adapting our source code
to your own examples. |

|
 |