You are here: irt.org | Articles | JavaScript | Image | Toolbar Images [ previous next ]
Published on: Saturday 17th May 1997 By: Martin Webb
This article will explain how to expand the two previous highlighting image articles (Highlighting Images and Highlighting Images (#2)) to obtain the white version of the images and the addition of status bar messages.
This will then be extended further to describe how to add the functionality to an automated frame based toolbar.
This following JavaScript will only provide the above functionality in a browser that supports at least JavaScript 1.1 although some limited functionailty will be available to JavaScript 1.0.
This JavaScript will also use a *.js file to hold all the JavaScript that does not have to be held in the main document, as this will reduce the amount of code that has to be reloaded each time the document changes. As image highlighting is only available in browsers that support JavaScript 1.1, this shouldn't pose a problem unless your server has not been correctly setup to serve the *.js mime types. (FAQ #5)
A simpler source code version is available if this effects you.
The following code will demonstrate how to create a simple two page demo (home and test).
Before we attempt to pre-load the images we must first check which browser is being used.
This check has been upgraded to check and allow for Internet Explorer 4, which now supports the Image array in JScript.
<script language="JavaScript"><!-- var js = 1.0; //--></script> <script language="JavaScript1.1" src="image.js"></script>
Which defines a default value of 1.0 for the js variable, and refers to a separate image.js file, which contains the following extra code to increase the value of js if necessary:
Version = parseInt(navigator.appVersion); if (navigator.appName == 'Netscape') js = ((Version >= 4) ? 1.2 : ( (Version == 3) ? 1.1 : 1.0 )); else if (navigator.appVersion.indexOf('MSIE') != -1) js = ((Version >= 4) ? 1.1 : 1.0);
But, we can forget all of this browser specific checking, and simply replace it with a test for the Image object:
if (document.images) { // supports the Image object } else { // does not support the Image object }
Only pre-load images if the Image object is supported. The code required to do this is contained again within image.js:
if (document.images) { test0 = new Image(); test0.src = 'test0.gif'; test1 = new Image(); test1.src = 'test1.gif'; test2 = new Image(); test2.src = 'test2.gif'; home0 = new Image(); home0.src = 'home0.gif'; home1 = new Image(); home1.src = 'home1.gif'; home2 = new Image(); home2.src = 'home2.gif'; }
This uses the onMouseOver, onMouseOut and onClick events of the Link object.
Within the home.htm document the HTML would be as follows:
<img name="homeA" width="47" height="13" border="0" alt="Test" src="home2.gif" > <a href="test.htm" onMouseOver="return change('testA','test',1)" onMouseOut="change('testA','test',0)" onClick="change('testA','test',2)"> <img name="testA" width="47" height="13" border="0" alt="Test" src="test0.gif"></a >
To show the image within the test.htm document the HTML would need to be simply modified to show a different default image:
<a href="home.htm" onMouseOver="return change('homeA','home',1)" onMouseOut="change('homeA','home',0)" onClick="change('homeA','home',2)"> <img name="homeA" width="47" height="13" border="0" alt="Test" src="home0.gif"></a > <img name="testA" width="47" height="13" border="0" alt="Test" src="test2.gif" >
onMouseOver calls the change() function passing three parameters:
onMouseOut calls the change() function passing three parameters:
onClick calls the change() function passing three parameters:
The onMouseOver and onClick events are supported in JavaScript 1.0, therefore it is necessary to check that the Image object is supported before actually performing the image change.
The following dummy change() function is used to invoke the changeit() function:
<script language="JavaScript"><!-- function change(Name,Image,No) { if (document.images) return changeit(Name,Image,No); } //--></script>
The following changeit() function is again stored in image.js:
function changeit(Name,Image,No) { document.images[Name].src = eval(Image + No + '.src'); }
Rather then store each of the status messages within the main documents, they will be stored in the image.js file, with the following simple amendements:
if (document.images) { test0 = new Image(); test0.src = 'test0.gif'; test1 = new Image(); test1.src = 'test1.gif'; test2 = new Image(); test2.src = 'test2.gif'; test3 = 'Click here to test it'; home0 = new Image(); home0.src = 'home0.gif'; home1 = new Image(); home1.src = 'home1.gif'; home2 = new Image(); home2.src = 'home2.gif'; home3 = 'Click here to go home'; }
To display the message when the mouse is over the image, the following additional amendments also need to be made to the image.js file:
window.defaultStatus = ''; function changeit(Name,Image,No,Msg) { document.images[Name].src = eval(Image + No + '.src'); if (Msg) self.status = eval(Image + '3'); return true }
Which sets the default status message to blank, and when Msg is set to true displays the appropriate status message.
We now need to make the following additional changes to the main documents:
Within the home.htm document the HTML would be as follows:
<img name="homeA" width="47" height="13" border="0" alt="Test" src="home2.gif" > <a href="test.htm" onMouseOver="return change('testA','test',1,true)" onMouseOut="change('testA','test',0)" onClick="change('testA','test',2)" > <img name="testA" width="47" height="13" border="0" alt="Test" src="test0.gif" ></a>
To show the image within the test.htm document the HTML would need to be simply modified to show a different default image:
<a href="home.htm" onMouseOver="return change('homeA','home',1,true)" onMouseOut="change('homeA','home',0)" onClick="change('homeA','home',2)" > <img name="homeA" width="47" height="13" border="0" alt="Test" src="home0.gif" ></a> <img name="testA" width="47" height="13" border="0" alt="Test" src="test2.gif" >
When changing the status message on a onMouseOver event it is important that the value of true is returned.
The complete source code for home.htm:
<body> <script language="JavaScript"><!-- function change(Name,Image,No,Msg) { if (document.images) return changeit(Name,Image,No,Msg); } //--></script> <script language="JavaScript1.1" src="image.js"></script> <img name="homeA" width="47" height="13" border="0" alt="Test" src="home2.gif" > <a href="test.htm" onMouseOver="return change('testA','test',1,true)" onMouseOut="change('testA','test',0)" onClick="change('testA','test',2)" ><img name="testA" width="47" height="13" border="0" alt="Test" src="test0.gif" ></a>
The complete source code for test.htm:
<body> <script language="JavaScript"><!-- function change(Name,Image,No,Msg) { if (document.images) return changeit(Name,Image,No,Msg); } //--></script> <script language="JavaScript1.1" src="image.js"></script> <a href="home.htm" onMouseOver="return change('homeA','home',1,true)" onMouseOut="change('homeA','home',0)" onClick="change('homeA','home',2)" ><img name="homeA" width="47" height="13" border="0" alt="Test" src="home0.gif" ></a> <img name="testA" width="47" height="13" border="0" alt="Test" src="test2.gif" >
The complete source code for image.js:
if (document.images) { test0 = new Image(); test0.src = 'test0.gif'; test1 = new Image(); test1.src = 'test1.gif'; test2 = new Image(); test2.src = 'test2.gif'; test3 = 'Click here to test it'; home0 = new Image(); home0.src = 'home0.gif'; home1 = new Image(); home1.src = 'home1.gif'; home2 = new Image(); home2.src = 'home2.gif'; home3 = 'Click here to go home'; } window.defaultStatus = ''; function changeit(Name,Image,No,Msg) { document.images[Name].src = eval(Image + No + '.src'); if (Msg) self.status = eval(Image + '3'); return true }
The above code does not show the status messages on Internet Explorer 3, as the version of JScript is equivalent to JavaScript 1.0. However, some of the status messaging can be simulated using the setTimeout() function. The following code can be used if you need to support Internet Explorer 3, or if your server has not been correctly setup to serve the *.js mime types.
Within the home2.htm document the HTML would be as follows:
<body> <script language="JavaScript"><!-- window.defaultStatus = ''; var timerRunning = false; var timerID = ''; if (document.images) { test0 = new Image(); test0.src = 'test0.gif'; test1 = new Image(); test1.src = 'test1.gif'; test2 = new Image(); test2.src = 'test2.gif'; home0 = new Image(); home0.src = 'home0.gif'; home1 = new Image(); home1.src = 'home1.gif'; home2 = new Image(); home2.src = 'home2.gif'; } function change(Name,Image,No,Msg) { if (document.images) changeit(Name,Image,No); if (Msg) return changeStatus(Msg); } function changeit(Name,Image,No) { document.images[Name].src = eval(Image + No + '.src'); } function changeStatus(Msg) { self.status = Msg; if (!document.images) { if (timerRunning) clearTimeout(timerID); timerRunning = true; timerID = setTimeout('resetStatus()',1000); } return true } function resetStatus() { self.status = ''; return true; } //--></script> <img name="homeA" width="47" height="13" border="0" alt="Test" src="home2.gif" > <a href="test2.htm" onMouseOver="return change('testA','test',1,'Click here to test it')" onMouseOut="change('testA','test',0)" onClick="change('testA','test',2)" ><img name="testA" width="47" height="13" border="0" alt="Test" src="test0.gif" ></a>
Within the test2.htm document the HTML would be as follows:
<body> <script language="JavaScript"><!-- window.defaultStatus = ''; var timerRunning = false; var timerID = ''; if (document.images) { test0 = new Image(); test0.src = 'test0.gif'; test1 = new Image(); test1.src = 'test1.gif'; test2 = new Image(); test2.src = 'test2.gif'; home0 = new Image(); home0.src = 'home0.gif'; home1 = new Image(); home1.src = 'home1.gif'; home2 = new Image(); home2.src = 'home2.gif'; } function change(Name,Image,No,Msg) { if (js >= 1.1) changeit(Name,Image,No); if (Msg) return changeStatus(Msg); } function changeit(Name,Image,No) { document.images[Name].src = eval(Image + No + '.src'); } function changeStatus(Msg) { self.status = Msg; if (!document.images) { if (timerRunning) clearTimeout(timerID); timerRunning = true; timerID = setTimeout('resetStatus()',1000); } return true } function resetStatus() { self.status = ''; return true; } //--></script> <a href="home2.htm" onMouseOver="return change('homeA','home',1,'Click here to go home')" onMouseOut="change('homeA','home',0)" onClick="change('homeA','home',2)" ><img name="homeA" width="47" height="13" border="0" alt="Test" src="home0.gif" ></a> <img name="testA" width="47" height="13" border="0" alt="Test" src="test2.gif" >
Why not try out this example.
The above examples pass the Name of the anchor to the change() function. This allows us to use the same image twice within the same document, i.e. a toolbar at the top and the bottom of the page.
When using frames it is highly unlikely that we would need to toolbars. Therefore the following code does not pass the Name of the anchor.
The function change is passed four values, i.e. change(Image,No,Link,Msg):
For example, if in your document you have 7 links to other files:
<a href="file0.htm" ..> <a href="file1.htm" ..> <a href="file2.htm" ..> <a href="file3.htm" ..> <a href="file4.htm" ..> <a href="file5.htm" ..> <a href="file6.htm" ..>
Each of them is stored in the Links array starting from position 0 upto position 6.
The third parameter passed should equal this index number.
The following code is placed within the frame.htm document, which defines the frameset and holds the common JavaScript:
<html> <head> <script language="JavaScript"><!-- window.defaultStatus = ''; function change(Image,No,Link,Msg) { if (document.images) { if (Link == -1) { window.menu.document.images[Image].src = eval(Image + No + '.src'); } else { if ( window.menu.document.links[Link].href != window.main.location.href ) window.menu.document.images[Image].src = eval(Image + No + '.src'); if (Msg) self.status = eval(Image + '3'); } } } function reset(Image,No) { if (document.images) { if (Image != 'home') change('home',0,-1); if (Image != 'test') change('test',0,-1); change(Image,No,-1); } } if (document.images) { test0 = new Image(); test0.src = 'test0.gif'; test1 = new Image(); test1.src = 'test1.gif'; test2 = new Image(); test2.src = 'test2.gif'; test3 = 'Click here to test it'; home0 = new Image(); home0.src = 'home0.gif'; home1 = new Image(); home1.src = 'home1.gif'; home2 = new Image(); home2.src = 'home2.gif'; home3 = 'Click here to go home'; } //--></script> </head> <frameset rows="100,*" frameborder="0" framespacing=0 border="0" > <frame src="menu.htm" name="menu" frameborder="0" marginheight="10" marginwidth="10" border="0" scrolling="no" noresize > <frame src="main.htm" name="main" frameborder="0" marginheight="10" marginwidth="10" border="0" > </frameset> </html>
There is not much difference between this code and that used before, except for the need to reference the menu frame, and check whether the location of the menu frame is equal to the href stored in the Links array.
The reset() function is used to reset all the images, except the current image for the current document loaded in the main frame. It passes -1 as the third parameter to the change() function.
The change() function then uses this number to correctly control whether the image should or shouldn't change on onMouseOver and onMouseOut events.
The menu.htm file contains the definitions of the images:
<body> <a href="home3.htm" target="main" onMouseover="parent.change('home',1,0,true)" onMouseout="parent.change('home',0,0)" onClick="parent.reset('home',2)" > <img name="home" width="47" height="13" border="0" alt="Home" src="home0.gif" ></a> <a href="test3.htm" target="main" onMouseover="parent.change('test',1,1,true)" onMouseout="parent.change('test',0,1)" onClick="parent.reset('test',2)" > <img name="test" width="47" height="13" border="0" alt="Test" src="test0.gif" ></a>
The only changes required, are the different set of parameters passed, and referencing the change() function within the parent frame.
The code required in the home3.htm and test3.htm documents very simple indeed:
<body onLoad="parent.reset('home',2)"> <h1>Home</h2> </body>
<body onLoad="parent.reset('test',2)"> <h1>Test</h2> </body>
Which both ensure, that if they are loaded by another means, i.e. without the use of the menu toolbar, then the appropriate image in the menu toolbar is still set to the correct image.
Note: If any of the links are to the same document then the script will not work properly.
Macromedia Fireworks Image Map Tutorial