JavaScript Lesson 9, Programming the Browser

The images[] array

So far you have met a couple of properties of the document object and a method that it contains, but there is a lot more to document than that. For instance, you probably didn’t know that it contains a list of all the images and all the hyperlinks that are displayed in a web page. The images are all recorded in an array called images[] and the links are recorded in an array called ... wait for it ... links[].

Suppose you had an HTML file which contained the following text

<html>
<img src="mypic1.gif"> This is my home page <img src="mypic1.gif">
<br />
I hope you like cats because this web page is all about cats.
<div align="center">
<a href="tibbles.html">Click here to see my own pet</a>
<br />
<img src="manycats.gif" width=70%>
</div>
<a href="about_me.html">Learn about me</a>
</html>

When this web page is loaded into the browser, the array images[] would contain three elements: images[0] would refer to the first picture(i.e. the first occurrence of mypic1.gif), images[1] would refer to the second picture (i.e. the second occurrence of mypic1.gif) and images[2] would refer to the third picture (i.e. manycats.gif). It wouldn’t make any difference if the browser were unable to load any particular image or not ... the array entry would still be the same. Similarly, links[0] would refer to the link to file tibbles.htm and links[1] would refer to the link to file about_me.htm, and again, it wouldn’t make any difference if the destination didn’t exist or not. The array entry would still be the same.

These arrays themselves hold objects, which contain properties. The images[] array holds objects of type Image, and each image has a source (i.e. the name of the file where the image is located), a width, a height etc. For instance, the filename for the first image in the example above is given by the following:

document.images[0].src

Note that the array must be referred to as part of the document object (with a full stop separating it from the word document, just as in document.bgColor) and that it is the src property of the array entry that we are interested in (corresponding to the src=... part of the original <img> tag). If you wanted to view the filename that a particular image was loaded form (say the last image on the page), you would insert a JavaScript program which said the following:

<script language="JavaScript">
alert(document.images[2].src);
</script>

This would display the filename manycats.gif in an alert() box. More importantly, you can change the filename (and therefore the image that is displayed) after the web page has loaded into the browser. Simply change the src property of the image to the new filename:

document.images[2].src = "topcat.jpg";

In this case, you would have to enclose the new filename within quotation marks. The image would change before your very eyes on the screen!

The links[] array

The links[] array contains objects which have an href property, corresponding to the href=... attribute in the <a> ... </a> tag. You can display the destination of a link using the following line:

document.write("The link leads to " + document.links[4].href);

Similarly, if you want to change the destination of the link, you just reassign this property to another string:

document.links[106].href = "http://www.richardbowles.co.uk";

(You have to include the http:// part on that, I find!) In this case, unlike changing the src property of the entries in the images[] array, you don’t actually see an immediate change on the screen. The first that the user of the program becomes aware of the change is when he/she clicks on the link and it goes to somewhere where it didn’t lead before! Similarly, the "clickable" part of the link can be an image, rather than text - it makes no difference.

Of course, the element to the array can be a variable or an expression. For instance, the following:

var x = 2;
document.links[2 * x + x * x * 3].href = homesite;

is equivalent to changing the value of document.links[16].href. You notice that in this case, the string which represents the new destination of the link is itself a variable. At some point, you would have had to set this string variable to the destination site, for instance as follows:

var homesite = "http://www.hotmail.com";

Similarly, the following code would produce a list of all the image source files on the screen:

for (x = 0; x < document.images.length; x++)
  document.write(document.images[x].src + "<br />");

A special trick

You may have spotted a slight problem. If you insert another image into the web page while you are editing it, or another hyperlink, then many of the references to the images in the images[] and links[] arrays will need to be changed as well. For instance, if a web page contains 10 images (numbered 0 to 9 in the images[] array, of course), then inserting a new one at the start of the web page will mean you have to go through the entire program, changing images[0] to images[1] etc.

The creators of JavaScript realised this too, so they provided us with a handy trick. In the case of the images[] and links[] arrays, you can use a string as the array index. This won’t work with ordinary arrays, so don’t try it with arrays that you have set up yourself in your own program.

Firstly, we have to add something to the image tag - a name:

<img src="family.gif" name="photo" id="photo" />

In this case, the NAME=photo part specifies that the name of this image is photo. Now we can refer to the image as follows:

which_image = document.images["photo"].src;
document.images["photo"].src = "cousin.jpg";		// etc.

It seems strange that we are using a string to index an array, but JavaScript is prepared to interpret it as the correct number when the program runs. The browser will work out for itself what the proper number for the image is. We could use string variables or even expressions for the index, as follows:

var v1 = "photo";
var v2 = "pho";
document.images[v1].src = "pic2.jpg";
document.images[v2 + "to"].src = "another.gif";

These are perfectly legal ways of doing it, although they seem horribly clumsy! The same thing applies to links. As before, we give the link a name ...

<a href="http://www.mysite.com" name="link1" id="link1"> My home page</a>

and then we can refer to it by quoting that name as the array index:

alert(document.links["link1"].href);

Suddenly we can insert as many images as we like into the file willy-nilly, knowing that we won’t have to rewrite any of the code.

Warning!

N.B. I have occasionally had some difficulty getting the last part working. Although my JavaScript text book tells me quite specifically that you should be able to use a string constant or a string variable in place of the index in the links[] array, there are times when it just won't work, for no logical reason. It works perfectly all the time with the images[] array, and indeed most of the time with links[], but on some occasions, it simply refuses to work!

That's why I tend to stick to numbers or numeric expressions when I refer to the links[] array.

A rollover effect

You may notice that some web sites have a special effect on them whereby an image will change when you move the mouse over it (without actually clicking on the image). Similarly, when you move the mouse away from the image, it goes back to the way it was. This effect is called a rollover, and it can be implemented by manipulating the images[] array in the document object. However, in order to implement a rollover, I am going to have to introduce you to two new events ... ONMOUSEOVER and ONMOUSEOUT. Baby
Roll over me!

You met events a few chapters ago, when you learned about HTML forms (remember the ONCLICK event?) This works similarly, except that the ONMOUSEOVER event is triggered whenever the mouse pointer moves into the space occupied by an object, and the ONMOUSEOUT event is triggered whenever the mouse pointer moves out of that space, i.e. away from the object. They are used as follows:

<img src="pic1.gif" onmouseover="hello();" onmouseout="goodbye();" />

In this case, the image, whose source file is pic1.gif, of course, is set up to react to both events. When the user moves the mouse pointer on top of the image, the function hello() is activated, and when the mouse pointer leaves the image, the function goodbye() is activated. There is no reason why the image shouldn’t have an onclick event handler as well, of course:

<img src="pic1.gif" onmouseover="hello();" onmouseout="goodbye();" onclick="fireUp();" />

In this case, the image would react to mouse clicks as well, by activating the fireUp() function. These events occur for all images in your web page, whenever you move the mouse onto or away from them. However, most images in your web pages won’t be set up to react to these events and they go unnoticed. We will make one further change ... we will add a name to the image, so that we can refer to it safely:

<img src="pic1.gif" onmouseover="hello();" onmouseout="goodbye();" name="magic" id="name" />

To implement the rollover, the function hello() should change the source file of the image. Of course, it can do other things as well, but we won’t bother with those:

function hello ()
{ document.images["magic"].src = "second.gif";
  // Do other things if you want
}

In this case, when the mouse pointer is moved on top of the object, the image changes to second.gif. Similarly, the function goodbye() should change the image back again to the original image:

function goodbye ()
{ document.images["magic"].src = "pic1.gif";
  // Do other things if you want
}

Of course, there is nothing to stop you setting up goodbye() so that it changes the image to a third, completely unrelated image, or even odder things, such as producing an alert box etc.

The location object

This is another object built into JavaScript, and it is a younger brother to the document object. It is not really that useful, as it simply describes the current location (file or web site address) that is displayed by the browser. It too has an href property, which always contains the address of the page that is currently displayed in the browser.

Link destination

For instance, if you created an HTML file called test.htm which was saved on the desktop and which contained the following code:

<script language="JavaScript">
alert(location.href);
</script>

loading it into the browser would produce the output shown:

Of course, there is no reason why you shouldn't alter the href property, which has the effect of changing the page viewed in the browser. It has the same effect as if you had clicked on a link to take you to some other page, except that the user didn't need to click on any link to do it - it happened under the program's control:

location.href = "myPage2.html";
var new_address = "http://www.yahoo.com";
location.href = new_address;

In fact, the location object gives us a method which does almost the same thing. The replace() method causes a jump to the new address as well:

location.replace(new_address);
location.replace("http://www.tesco.com");

The only difference is that the replace() method does not add the page you are just leaving to the history of the pages you have visited (i.e. when you click on the "Back" icon, you will find that the browser has forgotten the page that you just left) whereas changing href directly does add the page to the history.

The history object

Another brother of the document object `is the history object. This keeps track of all the pages that you have visited so far The "history" of a web visit is a list of page addresses maintained by the browser, so that when you click on the "Back" icon once or several times, it will take you back through the list one page at a time. Similarly, browsers have a "Forward" button so that you can move forward through the history list.

The history object lets you do exactly the same things, except under the control of a JavaScript program. It has a length property, which tells you how many pages there are in the list (display the value of history.length to find this out). It also has three methods:

The method history.back() is exactly equivalent to clicking the "Back" icon once - it takes you back one page in the history. Similarly, the method history.forward() is equivalent to clicking on the "Forward" icon once - the current page disappears and the one which is one step forward in the history takes its place. Of course, if you are at the end of the history (i.e. there are no pages to move forward onto), then the forward() method does nothing.

There is another method built into the history object called go(), which is slightly more flexible. This lets you move as many pages as you like forward or backward throughout the history - it is like a time machine! Just give the method a number as a parameter to tell it how many pages to move forward or backward:

history.go(-3); // Move to a page 3 back in the history
history.go(5);  // Move to a page 5 forward in the history
history.go(-1); // This is equivalent to history.back();
history.go(1);  // This is equivalent to history.forward();

Of course, the parameter can be a variable or an expression that produces some whole number. If you use the history.go() method to skip over intervening pages, then those pages aren't displayed on the screen, even for a split second. The browser jumps over those pages without even trying to load them.