Welcome to Australian PC User Magazine Offline CD-ROM
Software - What's on our latest cover CD. What's New - Like . . "What's new?" Net Guide - Our comprehensive guide to using the Net Web Workshop - Tutorials for Web developers Net Sites - Check out the best on the Web About Us - Find out about PC User Magazine and PC User Net nineMSN
clear.gif (118 bytes)
Web Workshop Contents

Home
Search
Help!

Graphic Web site menus - using JavaScript to create graphical menus

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.

 

WORK1s.gif (1360 bytes)
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.

 

WORK2s.gif (1929 bytes)
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.

 

WORK3s.gif (2237 bytes)
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>

WORK4s.gif (1832 bytes) 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.

corner.gif (190 bytes)

clear.gif (118 bytes)

toppage.gif (1757 bytes)copyrite.gif (1355 bytes)