Tải bản đầy đủ (.pdf) (50 trang)

the book of javascript 2nd edition phần 4 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (606.22 KB, 50 trang )


KEEPING TRACK OF
INFORMATION WITH ARRAYS
AND LOOPS
The last chapter showed you how JavaScript
stores radio buttons and pull-down menu
options in lists. In programmer’s parlance,
lists are called arrays. This chapter will teach you
how to create your own arrays and use them to keep
track of large amounts of information.
In this chapter, you’ll learn how to:
z Use JavaScript’s built-in arrays to control your HTML
z Create new arrays of your own information
z Use loops to search through arrays for information
Real-World Examples of Arrays
JavaScript’s built-in arrays are useful in a wide variety of applications. One
of the sites I work on, , uses JavaScript’s built-in
arrays to show users which species of ants live in various counties in the
124 Chapter 8
San Francisco Bay Area (see Figure 8-1). At the bottom of the list of counties
is a Select All checkbox. Clicking this box causes all the other checkboxes to
become checked. This trick is easy to script because the checkboxes are stored
in an array, allowing me to use JavaScript to check off each one. Browse to
to see this in action.
Figure 8-1: AntWeb checkboxes
Creating your own arrays can be useful as well. The Book of JavaScript
website employs arrays to show visitors a series of JavaScript programming
tips. In the textarea in Figure 8-2, you’ll see one of a dozen programming tips
that rotate through this box. I store these tips in a JavaScript array and rotate
through the array to put different tips into the textarea. The same principle
applies to making a timed slide show, which we’ll see in the next chapter.


Figure 8-2: Rotating programming tips on the Book of
JavaScript home page
JavaScript’s Built-In Arrays
When a web browser reads an HTML page, it automatically creates a number
of arrays. In the previous chapter we saw that JavaScript creates an array for
each set of radio buttons with the same name. If you create a set of radio
buttons named
age inside a form named the_form, you can refer to the first
radio button in the set like this:
window.document.the_form.age[0]
Keeping Track of Information with Arrays and Loops 125
JavaScript also creates an array for the options in each pull-down menu
and scrollable list. Here’s how you could access the second option in a pull-
down menu named
gender:
window.document.the_form.gender.options[1]
These are just two of JavaScript’s automatically created arrays. Browsers
also automatically create an array of all the
image objects on a web page,
called
images. The same holds true for form elements (the array of form
elements is called
elements). In Figure 8-3 (part of the Document Object
Model), you can see which elements (the boxes with the words array of in
them) get automatically created arrays.
Figure 8-3: Part of the DOM showing arrays in the document object
Each of these arrays is built based on how the page’s creator has written
its HTML. In the
images array, for example, the first image on a web page is
called

images[0], the second is images[1], and so on. If you use the images array,
you don’t have to name your images to swap them (as in “Swapping Images”
on page 58). For example, you can swap the first image on a web page with
an image called happy.gif with this line:
window.document.images[0].src = 'happy.gif';
THE CURRENT WINDOW
self, window,
parent, top
various
Window objects
navigator
Navigator
object
frames[]
array of
Window objects
location
Location
object
history
History
object
document
Document
object
Package
JavaPackage
object
elements[]
array of HTML

Form element
objects:
Button
Checkbox
FileUpload
Hidden
Password
Radio
Reset
Select
Submit
Text
Textarea
options[]
array of
Option objects
plugins[]
array of
Plugin objects
mimeTypes[]
array of
MimeType objects
forms[]
array of
Form objects
embeds[]
array of
JavaObject objects
applets[]
array of

JavaObject objects
images[]
array of
Image objects
anchors[]
array of
Anchor objects
mimeType[]
array of
MimeType objects
126 Chapter 8
Why would you want to use built-in arrays instead of just naming HTML
elements? Sometimes you have no choice. As we saw in Chapter 7, because
all the radio buttons in a set have the same name, you can access them only
using the built-in array.
Built-in arrays are also useful when you have many elements on a page.
If you have a web page with 100 images, naming them all becomes tedious.
Instead, you can just refer to each image by its number (for a set of 100 images,
the numbers would be 0 to 99).
The best thing about arrays, however, is that a little bit of JavaScript can
act on each element in the array—a great time-saving feature if you have a
100-element array. In the AntWeb example, clicking one checkbox (Select
All) checks all the individual county checkboxes. It doesn’t matter whether
you have a lone checkbox or a thousand of them—the code is the same.
To control an entire array as the AntWeb script does, your code needs to
determine how many elements the array contains and then go through each
element in the array, performing whatever action you want on it. AntWeb,
for example, figures out how many checkboxes there are and then checks
each one.
Figuring Out How Many Items an Array Contains

In all modern JavaScript-enabled browsers, an array’s length property contains
the number of elements in an array. For example, the script in Figure 8-4
figures out how many images a web page holds.
<script type = "text/javascript">
<! hide me from older browsers
X var num_images = window.document.images.length;
alert("There are " + num_images + " images on this page. ");
// show me >
</script>
Figure 8-4: How many images a web page contains
Drop this JavaScript into the bottom of a web page with images, and
you’ll see how it works. The critical line is X, which tells JavaScript to create
a variable called
num_images and set it to the number of images in the built-in
images array. If the page has 10 images, num_images will equal 10.
Going Through Arrays
Once you know how many elements are in an array, you need to write some
code that goes through each element. If you have a list of four checkboxes
and want to check them all, you could write a script like Figure 8-5.
<html>
<head>
<title>Checking Four Checkboxes</title>
Keeping Track of Information with Arrays and Loops 127
<script type = "text/javascript">
<! hide me from older browsers
function checkFour()
{
window.document.the_form.elements[0].checked = true;
window.document.the_form.elements[1].checked = true;
window.document.the_form.elements[2].checked = true;

window.document.the_form.elements[3].checked = true;
}
// show me >
</script>
</head>
<body>
<form name = "the_form">
<input type = "checkbox"> One <br>
<input type = "checkbox"> Two <br>
<input type = "checkbox"> Three <br>
<input type = "checkbox"> Four <br>
<input type = "button" value = "check 'em" onClick = "checkFour();"> <br>
</form>
</body>
</html>
Figure 8-5: Checking four checkboxes
With 1,000 checkboxes the function would end up 1,000 lines long, each
line identical to the one before it except for the number between brackets.
Writing this would be very tedious.
Worse, sometimes, when a page is dynamically generated (see
Chapter 13), you don’t know how many checkboxes will appear on a
page. In this case, it would be impossible to write a function like the one
in Figure 8-5.
You can avoid both these problems with a loop. A loop allows you to
execute the same JavaScript statements multiple times with slight variations.
For example, a loop could execute the following line 1,000 times, changing
the number in the brackets each time.
window.document.the_form.elements[0].checked = true;
The checkFour() function in
this script goes through each of

the four checkboxes and sets its
checked property to true (see the
result in Figure 8-6). But this code
is not the best solution, since it
only works for four checkboxes.
To work with five checkboxes,
you’d have to add another line
to the function.
Figure 8-6: The checkboxes checked
128 Chapter 8
while Loops
One kind of loop is called a while loop. In plain English, this translates to
“While such-and-such is true, do the following.” Figure 8-7 shows a
while loop
that prints the word happy three times.
<html>
<head>
<title>I'm Happy and I Know It</title>
</head>
<body>
I'm <br>
<script type = "text/javascript">
<! hide me from older browsers
X var index = 0;
Y while (index < 3)
Z {
[ window.document.writeln("happy<br>");
\ index = index + 1;
] }
^ // show me >

</script>
and I know it!
</body>
</html>
Figure 8-7: Printing the word happy three times with a
while loop
Loops are a very common programming technique. They may seem
strange the first couple of times you see them, but they are so common that
after a while you’ll understand them on sight.
The typical
while loop starts with a variable set to zero, as in X of
Figure 8-7. The variable
index is just like any other variable.
Once you’ve set this variable, the
while loop begins. Line Y reads, “While
the variable
index is less than three, execute the JavaScript between the
curly brackets (Z and ]).” The format of this line is important. The word
while must be lowercase, and the Boolean test index < 3 must fall between
parentheses.
When JavaScript sees Y, it checks whether the variable
index has a value
less than 3. If so, the script runs the lines between the curly brackets Z and ].
When we start,
index is 0, which is less than 3, so the script executes the two
lines between Z and ]. Line [ writes the word happy to the web page, and \
adds one to
index, changing it from 0 to 1.
Once we execute \ and reach the curly bracket in ], JavaScript jumps
back to Y to see if

index is still less than three. This is the nature of the while
loop. Every time JavaScript reaches a loop’s closing curly bracket (]), it
jumps back to the beginning of the loop (Y) to see whether the test in the
parentheses is still true. Because 1 is less than 3, JavaScript executes [, which
prints happy again; it then executes \, adding 1 to
index (which now has a
value of 2).
Keeping Track of Information with Arrays and Loops 129
Again, because we’re in a while loop, JavaScript jumps from ] to Y and
checks to see whether
index is still less than 3. It is, so [ and \ execute again.
The word happy appears a third time, and the script increments
index from
2to 3.
Once again, JavaScript jumps from ] to Y and checks to see whether
index is less than 3. This time, however, index is equal to 3, so the test (index < 3)
is not true. The
while loop stops and JavaScript jumps to ^, the line after the
closing curly bracket.
Many people have a hard time with looping, so make sure you understand
how it works. You may find it helpful to translate Y into plain English: “While
index is less than 3, write happy and add 1 to index.”
while Loops and Arrays
Now that you know how while loops work, you can apply them to arrays.
Look back at the function in Figure 8-5, and notice that each of the four
lines is more or less the same:
window.document.the_form.elements[some_number].checked = true;
The only difference is the number between the square brackets. Now
think about the variable
index in Figure 8-7. Its value increases by 1 each time

the script goes through the loop. This feature makes the
index variable ideal
for accessing each element in an array. Figure 8-8 uses
index to create a more
flexible version of Figure 8-5.
<html>
<head>
<title>Checking Four Checkboxes</title>
<script type = "text/javascript">
<! hide me from older browsers
function checkFour()
{
X var index = 0;
Y while (index < 4)
Z {
[ window.document.the_form.elements[index].checked = true;
\ index = index + 1;
] }
^ }
// show me >
</script>
</head>
<body>
<form name = "the_form">
<input type = "checkbox"> One <br>
<input type = "checkbox"> Two <br>
<input type = "checkbox"> Three <br>
<input type = "checkbox"> Four <br>
<input type = "button" value = "check 'em" onClick = "checkFour();"> <br>
130 Chapter 8

</form>
</body>
</html>
Figure 8-8: Using a loop to check four checkboxes
The critical line is [, which says, “Set form element number index to
true.” The first time through the loop, index is 0, so [ checks the first form
element (the first checkbox). Then \ adds 1 to
index, changing index from
0 to 1. JavaScript reaches ] and jumps back to Y, executes [ and \ because
index is less than 4, and repeats the process until index equals 4. When index
equals 4 and JavaScript jumps to Y, the
while loop ends (because index is no
longer less than 4) and JavaScript jumps to ^, the line after the closing curly
bracket.
Combining
while loops and arrays is extremely common, so make sure
you comprehend the process. The advantage of this kind of code is that it
works whether you have just a few checkboxes or a few thousand. To get the
code to work for, say, 4,000 checkboxes, you would just change the number
in Y from 4 to 4,000. The loop will then run 4,000 times, starting with 0 and
finally ending when
index equals 4,000.
Going Off the Deep End
The script in Figure 8-8 looks at the values of form elements 0 through 3,
which are the four checkboxes at the start of the form. The next form
element in the figure is the button. All
input elements have a checked value,
although it doesn’t really do anything for a button, so
window.document.the_form.elements[4].checked
will always be false. But what about this:

window.document.the_form.elements[5].checked
Here, we’re asking JavaScript to look at the checked value of whatever is
stored in the sixth spot in the
elements array. Sadly, there’s nothing there;
there are only five elements in this form, so JavaScript will respond with the
special word
undefined. Then, when you ask JavaScript to find the checked
value of this undefined thing, it gets confused and you get a JavaScript error.
You can prevent this kind of error by making sure that the values stored
in the array are defined, like this:
if (window.document.the_form.elements[5] != undefined) {
var checked_value = window.document.the_form.elements[5].checked;
}
Notice that there are no quotes around the word undefined. It’s a special word
like
true and false.
Keeping Track of Information with Arrays and Loops 131
Using array.length in Your Loop
The code in Figure 8-8 works well, but it could use one improvement. In
general, it’s best to have as few literal numbers in your code as possible:
Using specific numbers tends to make code apply only in specific situations.
In Figure 8-8, for example, Y works only when exactly four checkboxes
appear on the page. If you add another checkbox to the web page, you’ll
have to remember to change the
4 in Y to 5. Rather than rely on your memory,
you should let the computer do the remembering. You can rewrite Y like this:
while (index < window.document.the_form.elements.length)
The expression window.document.the_form.elements.length always equals
the number of form elements on a page, since adding another checkbox
automatically increases the length of the

elements array.
An Incremental Shortcut
Lines like \ in Figure 8-8 are used so frequently that programmers have
come up with the shorthand
index++ to replace index = index + 1. That’s the
variable
index followed by two plus signs (++), and it saves you the hassle of
typing
index twice. We’ll be seeing many other shortcuts like this later.
Beware of Infinite Loops
You should avoid one common loop mistake like the plague. It’s so common
that it has a name: the infinite loop. Infinite loops happen when your code
enters a loop it can never exit. Figure 8-9 shows you the classic error.
var index = 0;
while (index < 10)
{
window.document.write("I am infinite! <br>");
}
Figure 8-9: The classic infinite loop—don’t try this at home
Running this script will make you sad, so please don’t try it. If you do run
it, the script will endlessly write I am infinite! to the page. To stop the script
from running, you’d have to quit the browser, which isn’t always easy when
you’re stuck in an infinite loop.
This loop is infinite because I forgot to add 1 to
index after writing “I am
infinite!” The
index variable starts at 0 and never changes, so index < 10 is
always true. Since the test
while (index < 10) is always true, the loop continues
until you exit the browser.

The only way to avoid accidentally writing an infinite loop is to exercise
caution. Whenever you write a loop, make sure the loop will exit at some
point.
132 Chapter 8
for Loops
Another type of loop is the for loop. You format while and for loops differently,
but they do the same things. Which loop you use is largely a matter of prefer-
ence. Though
for loops look a little more confusing at first, they are more
compact.
Figure 8-10 compares a
while loop and a for loop that perform exactly the
same task.
// while loop
X var index = 0;
Y while (index < 10)
{
window.document.writeln("hello<br>");
Z index++;
}
// for loop
[ for (var index = 0; index < 10; index++)
{
window.document.writeln("hello<br>");
}
Figure 8-10: Comparing a
while loop and a for loop
Both of the loops in Figure 8-10 write the word hello to a web page ten
times. The main difference between them is that X, Y, and Z in the
while

loop collapse into [ in the
for loop. The format of a for loop is as follows:
for (initializer; test; incrementer)
{
//
some JavaScript
}
All for loops start with the word for, followed by parentheses containing
three pieces of JavaScript, separated by semicolons. The first piece is a state-
ment that is said to initialize the loop. Usually this statement declares an index
variable and sets it to the starting number. In [ of Figure 8-10, the initializer
of the
for loop is var index = 0 (the same as X in the while loop). The sec-
ond parameter of a
for loop is the test, which, if true, means that the loop will
execute one more time and then test again. In [ of Figure 8-10, the test is
index < 10 (the same as Y in the while loop). The final piece is the incrementer, a
statement that changes the condition each time the loop repeats, usually by
adding a number to the index variable (like Z in the
while loop).
Whether you use
while loops or for loops is a matter of taste. You can
write
for loops in fewer lines, but while loops are a bit easier to read.
Some people prefer
for loops because they lower the risk of accidentally
getting into an infinite loop. In a
while loop, you can easily neglect to
put
index++ inside the curly brackets. In a for loop, it’s hard to forget

to put this element inside the parentheses because you always have three
expressions there.
Keeping Track of Information with Arrays and Loops 133
How AntWeb Checks Off All the Checkboxes
Figure 8-11 shows a stripped-down version of how AntWeb uses loops to check
off all the checkboxes when a visitor clicks Select All.
I’ve taken out AntWeb’s HTML formatting, along with the repetitive
code for several of the counties, but the
checkAll() function is exactly the
same as AntWeb’s. To see the complete AntWeb page in all its formatting
glory, browse to /><html>
<head>
<title>AntWeb's Use of Arrays and Loops</title>
</head>
<body>
X <form name = "bayAreaSearchForm">
Y <input type = "checkbox" name = "counties" value = "alameda">Alameda<br>
<input type = "checkbox" name = "counties" value =
"contra costa">Contra Costa<br>
<input type = "checkbox" name = "counties" value = "marin">Marin<br>
Z <input type = "checkbox" name = "selectall"
onClick = "selectAll(window.document.bayAreaSearchForm);">Select All<br>
</form>
<script type = "text/javascript">
<! hide me from older browsers
[ function selectAll(thisForm) {
\ var count = thisForm.counties.length;
] var checkedVal = thisForm.selectall.checked;
^ for (var loop = 0; loop < count; loop++) {
_ thisForm.counties[loop].checked = checkedVal;

}
}
// show me >
</script>
}
</body>
</html>
Figure 8-11: AntWeb’s use of arrays and loops
Line-by-Line Analysis of Figure 8-11
The first few lines in Figure 8-11 describe the form that contains the check-
boxes. Line X names the form
bayAreaSearchForm, and Y and the two lines
after it describe each of the checkboxes. Line Z describes the checkbox that
causes the other checkboxes to become checked. This checkbox is named
selectall; clicking it calls the function selectAll(), which starts in [. Notice
in Z that when the function is called, the name of the form to act on is
passed to the function. In [, that form is named
thisForm inside the function.
The nice thing about this is that the
selectAll function will work on any
page, and for any form. You just need to pass the form into the function, as is
134 Chapter 8
done when the function is called in Z. Line \, the first line in the function’s
body, stores the number of elements in the form into a variable named
count.
There are four elements in this form—the three county checkboxes and the
Select All checkbox—so
count will be 4.
Line ] stores the
checked value of the selectall checkbox: either true,

if the checkbox was just checked, or
false, if it was unchecked. The real
fun begins with the loop, starting in ^. The first time through the loop,
the variable named
loop will have a value of 0, so thisForm.counties[loop]
in _ will point to the first element in the
bayAreaSearch form—the first
checkbox. The second time through the loop, the value of
loop will be 1,
so
thisForm.counties[loop] will point to the second checkbox. The loop
occurs four times, once for each checkbox.
You may be thinking that testing the fourth checkbox is a bit unnecessary,
and you would be correct. The fourth time through the loop, the script is
just setting the fourth checkbox to
checkVal, which already stores the value
of the fourth checkbox. Hence, the script is just setting the value of the
fourth checkbox to whatever the value already is. If I wanted to avoid this
unnecessary step, I could have changed the loop to this:
for (var loop = 0; loop < count; loop++) {
X if (thisForm.counties[loop].name != 'selectAll') {
thisForm.counties[loop].checked = checkedVal;
}
}
Here, X looks at the name of the checkbox. If it is anything other than
'selectAll', the JavaScript will change the checked value of the checkbox.
I decided to leave that out because the unnecessary effort taken by JavaScript
to change the
checked value of a checkbox is less than the effort that would be
required to examine the name of a checkbox and see whether it is

selectAll
each time through the script. With the types of tasks JavaScript is generally
used for, efficiency decisions like this don’t really save very much time.
However, if you notice that your script is taking a long time to run, make
sure code inside your loops does not take too long. Slow code that runs
once in a script isn’t too bad. Slow code that runs 1,000 times because it’s
in a loop might slow things down noticeably.
Creating Your Own Arrays
Arrays are so handy that you’ll often want to create your own. A phone book,
for example, is an array of names and phone numbers. You can think of a
survey as an array of questions; an array can also store the answers a visitor
enters. A slide show is an array of pictures shown in sequence.
Happily, JavaScript lets you create your own arrays. If you know what
you want to store in the array when you create it, use a line like the following:
var rainbow_colors =
new Array("red", "orange", "yellow", "green", "blue", "indigo", "violet");
Keeping Track of Information with Arrays and Loops 135
This line creates a variable called rainbow_colors that stores an array of colors.
The words
new Array() tell JavaScript to create a new Array object, just as
new Date() created a new Date object back in Chapter 2. To put values in your
new array, simply list them in the parentheses.
Everything you’ve learned about JavaScript’s built-in arrays also applies
to arrays you create yourself. Figure 8-12 uses the
rainbow_colors array to create
a psychedelic strobe effect on a web page.
<html>
<head>
<title>Strobe</title>
<script type = "text/javascript">

<! hide me from older browsers
function strobeIt()
{
X var rainbow_colors =
new Array("red", "orange", "yellow", "green", "blue", "indigo", "violet");
var index = 0;
Y while (index < rainbow_colors.length)
{
Z window.document.bgColor = rainbow_colors[index];
[ index++;
}
}
// show me >
</script>
</head>
<body>
<form>
<input type = "button" value = "strobe" onClick = "strobeIt();">
</form>
</body>
</html>
Figure 8-12: A psychedelic strobe effect
Line-by-Line Analysis of Figure 8-12
Line X in Figure 8-12 creates the array and Y sets up the loop, saying, “While
index is less than the number of items in the array, execute the JavaScript
between the curly brackets.” The first time through the loop,
index is 0, so
when Z looks up
rainbow_colors[index], it gets the first item in the array, the
value

red. Line Z assigns this value to window.document.bgColor, which sets the
background color to red. Once the script has set this color, [ adds 1 to
index,
and the loop begins again. Next time through,
index will be 1, so Z will make
the background color orange, [ then adds 1 to
index, making it 2, and back
through the loop we go. If you have a very fast computer, the background
may strobe too quickly for you to see it. In this case, add a few more colors
to the array in X.
136 Chapter 8
How the Book of JavaScript Tip Box Works
The Book of JavaScript website has a little textarea that shows various pro-
gramming tips. The script keeps these tips in an array and then uses JavaScript
to loop through the array, showing one tip at a time. Each tip stays in the
textarea for 3.5 seconds before the next one appears. I should confess that I
got the idea for this tip box from something that the search engine Ask.com
(, formerly known as Ask Jeeves) once had on its home
page. In fact, I will present two different versions of the code. The first
version, shown in Figure 8-13, is very similar to the code Ask.com originally
used. The second version, which you’ll see in Figure 8-14, is a bit simpler
(though not necessarily better).
The code in Figure 8-13 is similar to code from Ask.com and contains
many little tricks that I haven’t yet covered. It starts out simply enough with
X, which says, “After the page has loaded, call the function
startScroll().”
The first line in the JavaScript tags, Y, creates an array called
tips and loads
it with a bunch of familiar programming adages. Line Z creates a variable
called

num_tips and sets it equal to the number of tips in the tips array.
<html>
<head>
<title>Arrays and Loops a la Ask.com</title>
</head>
X <body onLoad = "startScroll();">
<script type = "text/javascript">
<! hide me from older browsers
Y var tips = new Array("Don't forget to comment your code.", "Beware of infinite
loops.", "Program so that other humans can understand what you're doing.");
Z var num_tips = tips.length;
var index = 0;
[ while ((num_tips > 0) && (tips[num_tips-1] == ""))
{
num_tips;
}
function startScroll() {
\ if (num_tips != null) {
] if (window.document.tip_form) {
^ window.document.tip_form.tip_box.value = tips[index++];
_ if (index > num_tips - 1)
{
` index = 0;
}
}
a setTimeout("startScroll()", 3500);
}
}
// show me >
</script>

<form name = "tip_form">
<textarea name = "tip_box" rows = "3" cols = "30"></textarea>
Keeping Track of Information with Arrays and Loops 137
</form>
</body>
</html>
Figure 8-13: Ask.com-style use of arrays and loops
Checking for Blank Statements
The next couple of lines exhibit “paranoid” programming style. Paranoid
programmers make sure everything is perfect before they execute a line of
code that’s going to affect the user experience. Line [ and the line following
it, for example, make sure no blank statements (two quotation marks with
nothing between them) appear at the end of the
tips array. Who knows
why that would happen—but just in case, [ checks the last element in the
array. If it’s not blank, the loop ends. If it is blank, the line below it executes,
reducing
num_tips by 1. The loop then checks to see whether the second to
last element is blank. If it’s not, the loop ends. If it is, that line runs again,
reducing
num_tips by 1 once more. Notice that you can subtract one from a
variable with the syntax
variable_name You can also use ++variable_name
and
variable_name as shown.
Checking the Last Element in the Array
You might be wondering how [ checks the last element of the array. Remem-
ber,
num_tips equals the number of items in the array. If the array has three
items,

num_tips equals three. However, because the first element in the array
is zero, the last element in an array will be two—the length of the array minus
one. To look at the last element of an array, use the following line:
var last_element = the_array[the_array.length - 1];
If the array contains three elements, the_array.length equals 3, and
the_array.length minus 1 equals 2, which is the number JavaScript uses to
reference the last element in the array. You may be thinking, “There’s no way
I’d ever figure that out!” But don’t worry—this kind of array mathematics
becomes second nature after you’ve done it a few times.
Testing the Limits of Arrays
You may have noticed that before [ checks to see whether the last ele-
ment in the array is a blank string, it makes sure there is at least one tip in the
array. If there are no elements in the array,
num_tips will equal 0. If that’s the
case, then the second part of the
while loop would be checking to see whether
tips[0 – 1] == "", or doing the math, tips[-1]. Because arrays start at 0, there
will never be a value in position -1, so there’s really no reason to check what’s
in that position. When you have two parts to a test that contains
and, both
parts must be true for the whole thing to be true. JavaScript is smart enough
138 Chapter 8
to not bother checking the second part of a test with an and if the first part is
false. Why bother testing the second part if it already knows the whole thing
will be false?
The startScroll() Function
In the startScroll() function, we find more programming paranoia. Line \
checks to see whether the variable
count actually has a setting. If not, its
value is the special word

null. Line ] exhibits even more paranoia. Ask.com
makes sure the form named
rotate has been drawn to the page by checking
to see whether the form named
document.tip_form exists. If it does not exist,
document.tip_form is false, and the lines between the brackets of the if-then
statement won’t execute. I have never encountered any browsers that support
JavaScript but not forms. If they’re out there, however, ] makes sure JavaScript
won’t try to write to a form that doesn’t exist.
Line ^ looks up a tip in the array and writes it into the textarea. This line
tells JavaScript to find the form named
tip_form and the form element named
tip_box and sets its value to whatever appears on the right side of the equal
sign. The latter requires some explanation. Instead of just looking up the
value of element
index in the text array and then adding 1 to index, as in
document.tip_form.tip_box.value = tips[index];
index++;
line ^ looks up the value of element index and adds 1 to index right there:
document.tip_form.tip_box.value = tips[index++];
This is legal and saves some space, but it’s a little hard to read.
Going back to the notation introduced earlier, if Ask.com had done this,
document.tip_form.tip_box.value = tips[++index];
putting the plus signs in front of index, the JavaScript would add 1 to index
and then look for the value of
tips[index]. It’s the same as this line:
index++;
document.tip_form.tip_box.value = tips[index];
It’s rare to see people messing around with the location of the double
plus and minus operators. But if you run into this while looking at source

code, you’ll know what’s going on.
The next two lines, _ and `, are important for any program that con-
tinuously loops through an array. The JavaScript writes a tip in the textarea,
then moves on to the next tip in the array, until it runs out of tips. Once that
happens, the program should return to the first question in the array and
start all over. Lines _ and ` make this happen. Line _ determines whether
the last question has appeared. If the variable
index is more than num_tips - 1,
Keeping Track of Information with Arrays and Loops 139
we’ve reached the end of the array. Remember, Z set num_tips to the length
of the array, so
num_tips - 1 is the position of the array’s last element. If index
is greater than
num_tips - 1, we’ve reached the array’s end, and ` executes. It
sets the variable
index back to 0, so the next time the script puts tips[index]
into the textarea,
index will indicate the first question in the array.
Finally, a determines how fast the questions change in the textarea.
The next chapter will talk more about how the code in a works. For now,
you just need to know that it translates as, “In 3.5 seconds, call the function
startScroll() again.” Each time the script calls startScroll(), the function
puts a new question in the textarea and increments
index by 1.
A Streamlined Version
The code in Figure 8-13 is a bit confusing. Figure 8-14 shows you a streamlined
version that still works under most conditions.
Although the code in this version is more streamlined, it’s not necessarily
better. Paranoia is a good thing in programming. The more checks you put
in, the less likely your visitors are to encounter a JavaScript error. Given the

choice between the approaches demonstrated in Figures 8-13 and 8-14, I’d
recommend the former because it’s more robust. The code in Figure 8-14 is
merely easier to understand.
<html>
<head>
<title>Arrays and Loops</title>
</head>
<body onLoad = "scroll();">
<script type = "text/javascript">
<! hide me from older browsers
var tips = new Array("Don't forget to comment your code.", "Beware of infinite
loops.", "Program so that other humans can understand what you're doing.");
var index = 0;
function scroll() {
document.tip_form.tip_box.value = tips[index];
index++;
if (index == tips.length)
{
index = 0;
}
setTimeout("scroll()", 3500);
}
// show me >
</script>
<form name = "tip_form">
<textarea name = "tip_box" rows = "3" cols = "30">
</form>
</body>
</html>
Figure 8-14: A more streamlined version of the code in Figure 8-13

140 Chapter 8
Loops Can Nest
Just as you can nest if-then statements inside other if-then statements, you can
also put loops inside other loops. For example, Figure 8-15 shows you a script
that writes a solid rectangle of Xs to a web page, five Xs high and ten Xs
wide (see the result in Figure 8-16). Although this script doesn’t do anything
useful, it offers an idea of how nesting loops work.
X for (first_loop = 0; first_loop < 5; first_loop++) {
Y for (second_loop = 0; second_loop < 10; second_loop++) {
Z window.document.writeln("X");
}
[ window.document.writeln("<br>");
}
Figure 8-15: A simple example of nesting loops
Creating Arrays As You Go Along
If you’re giving someone a quiz and want to store the answers in an
array, you must create an array even though you don’t know what
values it will store. In such cases, you’ll need to build your array piece
by piece.
Start by creating an empty array, as in this line:
var the_answers = new Array();
This tells JavaScript to create a new array called the_answers, leaving
it empty.
Line X in Figure 8-15 sets up
a loop that will be executed five times.
Each time through that loop, the
second, or inner, loop (Y and Z) runs.
That loop writes the letter
X to the web
page ten times. After the inner loop

has run, [ in the outer loop writes a
<br> to the web page, creating a line
break. After [ runs, the loop in X
runs again. This happens five times.
Each time loop X runs, loop Y writes
a line of ten Xs, then [ writes a
<br>.
Loops inside loops can seem puzzling
at first, but they can come in handy.
Figure 8-16: The rectangle of Xs
created with nested loops in
Figure 8-15
Keeping Track of Information with Arrays and Loops 141
Once you’ve created the array, you can load values into it, like this:
the_answers[0] = "yes";
the_answers[1] = "no";
the_answers[2] = "maybe";
The first line puts the word yes into the first slot of the array, the next
puts no into the second slot, and the third line puts maybe into the third slot.
You can store values in an array in any order. Reversing the three lines above
wouldn’t make any difference. The word maybe goes into the third slot of the
array because the number 2 appears between the square brackets. Figure 8-17
demonstrates how to use this technique to create a Mad Lib, that party game.
<html>
<head>
<title>Mad Lib</title>
</head>
<body>
<script type = "text/javascript">
<! hide me from older browsers

X alert("This is a Mad Lib! Please fill in the blanks appropriately.");
Y var answers = new Array();
Z answers[0] = prompt("an animal","bear");
answers[1] = prompt("an adjective","happy");
answers[2] = prompt("a past tense verb","kissed");
answers[3] = prompt("an object","tree");
[ var the_string = "";
\ the_string = the_string + "Once upon a time there was a " + answers[0];
the_string = the_string + " who was very " + answers[1] + ".";
the_string = the_string + " In fact, he was so " + answers[1];
the_string = the_string + " that he " + answers[2] + " a " + answers[3] ".";
] window.document.writeln(the_string);
// show me >
</script>
</body>
</html>
Figure 8-17: A short Mad Lib
It’s not a very long Mad Lib, but you get the idea. When someone comes
to this page, the alert in X greets the visitor. After the alert, the script creates
a new, empty array in Y. The next few lines, starting with Z, fill the array.
Each of these lines uses the
prompt() function to ask a question (and display
a default answer) and then loads the visitor’s answer into the array. The first
answer goes into array position 0, the next into array position 1, and so on.
142 Chapter 8
By the time the script reaches [, the visitor has filled the array’s first four
positions. Line [ initializes a variable that stores the contents of the Mad
Lib. The next few lines, starting with \, build this string. Each line adds
content to the string. Line \ adds “Once upon a time there was a user
answer.” The next line appends “who was very user answer” to the end of the

string. Line ] writes the complete string to the web page.
Associative Arrays
All the arrays we’ve seen so far have stored values according to their numerical
position in the array. An associative array uses strings instead of numbers to
store values. For example, the following lines create a phone book with an
associative array:
var phone_book = new Array();
phone_book["dave thau"] = "(415) 555-5555";
phone_book["information"] = "(415) 555-1212";
The first line creates a new, empty array, as we’ve seen before. The next two
lines put two associations into the array. The first associates the string
dave
thau
with another string, (415) 555-5555. The second associates the string
information with the number to dial for Information. To retrieve that number,
you would look it up using a line like this:
var information_number = phone_book["information"];
This tells JavaScript to look in the array phone_book for the value associated
with the string
information. The string used to retrieve the association must
precisely match the string used to store it. Retrieving thau’s phone number
with the line
var thau = phone_book["thau"];
won’t work if you originally stored the information as
phone_book["dave thau"] = "(415) 555-5555";
Figure 8-18 shows how to use an associative array for a functional phone
book, and Figure 8-19 shows the page displayed by this code.
<html>
<head>
<title>Phone Book</title>

<script type = "text/javascript">
<! hide me from older browsers
X var phone_book = new Array();
Keeping Track of Information with Arrays and Loops 143
Y phone_book["blank"] = "";
phone_book["happy"] = "(555) 555-1111";
phone_book["sleepy"] = "(555) 555-2222";
phone_book["sneezy"] = "(555) 555-3333";
phone_book["sleazy"] = "(555) 555-4444";
phone_book["sneery"] = "(555) 555-5555";
phone_book["bleary"] = "(555) 555-6666";
phone_book["tweaked"] = "(555) 555-7777";
Z function displayNumber(the_phone_book, entry)
{
[ var the_number = the_phone_book[entry];
\ window.document.the_form.number_box.value = the_number;
}
// show me >
</script>
</head>
<body>
<h1>The Dwarves of Multimedia Gulch</h1>
] <form name = "the_form">
<b>Name:</b>
^ <select onChange =
"displayNumber(phone_book,this.options[this.selectedIndex].value);">
_ <option value = "blank"> Choose a Dwarf
<option value = "happy">Happy
<option value = "sleepy">Sleepy
<option value = "sneezy">Sneezy

<option value = "sleazy">Sleazy
<option value = "sneery">Sneery
<option value = "bleary">Bleary
<option value = "tweaked">Tweaked
</select>
<p>
<b>Number:</b>
<input type = "text" name = "number_box" value = "">
</form>
</body>
</html>
Figure 8-18: Creating a phone book using an associative array
Figure 8-19: The phone book page generated by the
code in Figure 8-18
144 Chapter 8
Line-by-Line Analysis of Figure 8-18
When a browser loads this page, it shows a pull-down menu with some names
and a text box that displays a phone number (Figure 8-19). Selecting a name
puts that person’s phone number in the text box. This neat little application
doesn’t take too much work to implement.
The script starts by creating a new array called
phone_book in X and then
filling it with the values in lines Y down. Note that the first element in the
array deals with the header line in the pull-down menu (_). If someone
selects Choose a Dwarf in the pull-down menu, that will put a blank string in
the phone number box.
After building the
phone_book array, Z defines a function as displayNumber().
This function takes two parameters: an array that holds the phone book
we want to use and a name we want to look up in the phone book. Line [

looks up the name in the phone book and stores it in
the_number. Line \
puts
the_number in the text box.
Line ] starts the form and names it
the_form. Line ^ is a bit more
complicated; it defines the pull-down menu and describes what should
happen when a visitor changes the value there. Changing the pull-down
menu selection triggers the
onChange event, which calls the displayNumber()
function. As described earlier,
displayNumber() takes two parameters: the phone
book and the name to look up. In this case, we have just one phone book,
called
phone_book. Later we might expand this script to include several phone
books—for example, one for friends, called
friends_book; one for business,
called
business_book; and one for favorite shops, called shop_book. Because
we can decide which phone book to use whenever we call the
displayNumber()
function, switching books is easy. If we wanted to use the
business_book phone
book, we’d just call the function like this:
<select onChange =
"displayNumber(business_book, this.options[selectedIndex].value);">
The second parameter in the function is the name to look up. If we
choose Happy, the person listed first in _ of Figure 8-18, the value
happy
passes to the function.

Play around with this example and make sure you understand how the
displayNumber() function works and how the values in ^ enter the function.
Summary
This chapter has introduced the last two fundamental ideas behind all
programming languages: arrays and loops. Now that you’ve learned about
variables,
if-then statements, functions, loops, and arrays, you’ve learned all
of the basic aspects of computer programming—so be happy! From now
on, everything we learn is specific to how JavaScript works with the browser.
All the tough programming nitty-gritty is behind us.
Keeping Track of Information with Arrays and Loops 145
Before you leave this chapter, make sure you’ve learned how to:
z Create a new array
z Access elements in an array
z Use loops to go through an array’s elements
z Use both for and while loops
z Nest loops
z Use associative arrays
Assignment
To make sure you understand everything in this chapter, try this assignment.
Write a script that creates bar charts. This script should first ask a visitor
how many bars to include in the chart. If the visitor wants four bars, the script
should then ask for four numbers, ranging from 1 to 10, and draw a bar
for each. Figures 8-20 through 8-22 demonstrate what I mean. To draw the
bars, create a square GIF, or use square.gif, which is available at http://
www.bookofjavascript.com/Chapter08/square.gif. If someone wants a bar
that’s ten squares high, use a loop to write
window.document.writeln("<img src='square.gif'>")
ten times to the page. This is another tough assignment, so give yourself
plenty of time to do it.

Figure 8-22: The bar chart
Figure 8-20: Asking visitors how many bars
they want
Figure 8-21: Asking for bar values

×