Chapter 3

Working with Objects and Events


CONTENTS

This chapter continues the discussion of JavaScript programming with some of the more advanced aspects of the language. You will learn some of the tools you can use to create complete, complex JavaScript applications-objects, functions and methods, forms, loops and conditionals, and event handlers.

Using JavaScript Objects

As mentioned in the previous chapter, JavaScript is an object-oriented language. An object is a custom data type that can combine data with functions to act upon it. The data items in an object are its properties, and the functions are its methods.

With some languages, such as C++, the term "object-oriented" sends many people running for cover. Object-oriented programming can be confusing with these languages. However, JavaScript's implementation of objects is very basic and easy to understand-in fact, you've used objects already-every array or string in JavaScript is an object.

Using Object Properties

Recall also that the bits of data stored in an object are called properties of the object. Properties can be numbers, strings, or even other objects. Each property has a name associated with it, which you must use to refer to that property.

To illustrate object properties, let's look at an object you've already used-the String object. Any variable that contains a string in JavaScript is actually a String object. This is an object built into the JavaScript language; you don't have to refer to it explicitly as an object.

Tip
You'll learn more about the String object, including its methods, in the Built-In Objects section of Chapter 4 "Using Built-In Objects and Custom Objects."

The String object has a single property called length. As you might have guessed, the length property indicates the current length of the string. You can use two different types of notation to refer to an object's property. The first and most common method is to separate the object name and property name with a period. For example, the following statement sets the variable len to the length of the address string variable:

len = address.length;

The second method is the one you use to refer to array elements, which are actually properties of an array object. This uses brackets around the property name. This example sets the len variable to the length of the address string, just as the previous example does:

len = address["length"];

Because this method can be used effectively to create an array with names instead of numbers for indices, it is also referred to as an associative array. This is an array with named values, which makes it very easy to deal with things such as database entries.

You can use either the bracket or period syntax interchangeably in most cases. The exception is when you are using a variable to hold the name of a property. For example, the following statements refer in a roundabout way to a string's length property:

x = "length";
len = address[x];

In this case, you have to use brackets for the property name. If you simply used address.x, the interpreter would look for a property called x, resulting in an error.

Note
You may be familiar with associative arrays if you have done any programming in Perl. The named properties in a JavaScript object provide a similar capability. Chapter 10, "Working with Multiple Pages and Data," includes an example of using associative arrays.

Assigning Values to Properties

In the previous examples, you've read the properties of the object, rather than writing to them. The string object's length property is a read-only property; you cannot set it to a value. However, other objects enable you to do this.

As another example, let's create an imaginary type of object called Card, which will store business cards. The Card object has the following properties:

Assuming you had created a Card object called card1, you could define its properties using these statements:

card1.name = "Sherlock Holmes";
card1.address = "221B Baker Street";
card1.work_phone = "555-2345";
card1.home_phone = "555-3456";

Later in this chapter, you'll work with the Card object more, and learn how to define and create objects.

Functions and Methods

As you can see, by using objects and properties you can easily store any type of data in JavaScript. Objects aren't just groups of data, though-they can also include ways of using the data, the methods. Methods are functions dedicated to the object.

Declaring a Function

Recall that a function is a set of JavaScript statements that accept one or more parameters and return a value. Even without using objects, you can use a function in JavaScript to perform a specific task. Chapter 2 "Working with Larger Programs and Variables," defined a function to add two numbers. This was a simple function, and a useless one-the addition operator does the same thing.

Let's try a more complex (and more useful) function. One handy use for functions is to avoid repetitive use of complex HTML codes to output information. For example, consider the <TABLE> tag in HTML 3.0. This example shows the HTML code to define a table of names, ages, and birthdays for several people:

<TABLE>
<TR> <TD>Fred</TD> <TD>27</TD> <TD>June 17</TD> </TR>
<TR> <TD>Tom</TD> <TD>24</TD> <TD>March 13</TD> </TR>
<TR> <TD>Rebecca</TD> <TD>25</TD> <TD>November 30</TD> </TR>
</TABLE>

The <TABLE> tag is required to start and end the table, the <TR> tag starts and ends table rows, and the <TD> tag starts and ends each cell within the row. As you can see, this can make for some complicated HTML.

If your JavaScript program is producing this information as output, it becomes that much more difficult, because you have to print each of the tags carefully in the right order. Listing 3.1 shows a JavaScript program to print the table shown previously.


Listing 3.1. A JavaScript program to print the table.
document.write("<TABLE>\n");
document.write("<TR> <TD>Fred</TD> <TD>27</TD> <TD>June 17</TD> </TR>\n");
document.write("<TR> <TD>Tom</TD> <TD>24</TD> <TD>March 13</TD> </TR>\n");
document.write("<TR> <TD>Rebecca</TD> <TD>25</TD> <TD>November 30</TD> </ÂTR>\n");
document.write("</TABLE>");

As you can see, this isn't exactly the most readable JavaScript program. A much better method is to use a function to perform the repetitive task-in this case, printing the <TR> and <TD> tags in the right order with each row of data. Listing 3.2 shows the definition for a PrintRow() function to perform this task:


Listing 3.2. The PrintRow function, for printing a table row.
function PrintRow(name, age, birthday) {
   document.write("<TR> <TD>", name, "</TD> <TD>", age, "</TD> <TD>", birthday,
 "</TD> </TR>\n");
}

The first line of the function definition includes the function keyword, which is required to begin a function definition. The function name, PrintRow, is then given. The parameters the function will expect are in the parentheses; these are also the names of variables, local to the function, which will be defined to store the parameters passed.

The statements that comprise the function begin with the left brace. In the second line, the document.write function is used to output the parameters, with the proper HTML table tags between them. Because this is the final statement in the function, it ends with a right brace.

Tip
Not all functions have parameters. You can define a function that doesn't require any parameters by using an empty parameter list: ().

Calling a Function

You now have a function that can be used to print a row of the table. In order to use it, you need to call the function. A function call is simply the name of the function and the parameters to send it.

Using function calls to the PrintRow() function defined in Listing 3.2, you can easily create the table of names, ages, and birthdays without unnecessary repetition:

document.write("<TABLE>\n");
PrintRow("Fred", 27, "June 17");
PrintRow("Tom", 24, "March 13");
PrintRow("Rebecca", 25, "November 30");
document.write("</TABLE>\n");

As you can see, although it's a simple one-line function, the PrintRow() function can save quite a bit of typing-especially if the table has more than three rows. It also creates more readable, clear JavaScript code. Compare this to the first program to print the table (Listing 3.1) and you'll see the difference.

Returning a Value

The function used previously accepted parameters, but did not return a value. A function can send a value back to the calling statement with the return keyword. This can be useful for a function that calculates a result; it can also be used to indicate success or failure.

The value returned by a function can be of any type-a number, a string, or even an object. As a simple example of returning values, let's define a function that returns a string. Once again HTML is used as an example. The function in Listing 3.3 provides a quick way to add boldface on/off (<B> and </B>) HTML tags to a piece of text.


Listing 3.3. A simple function to convert text to boldface HTML.
function Bold(text) {
   var temp = "<B>" + text + "</B>";
   return temp;
}

This function accepts a string as a parameter and stores it in the text variable. It then creates another variable called temp and concatenates the required tags to text. The temp variable is then returned.

Note
This function provides a good demonstration of the loosely typed nature of JavaScript. The function would actually accept any type of variable as a parameter; the only thing that implies that a string is required is the concatenation operator used in the second line.

The function call is slightly different for a function that returns a value, because you need to do something with the returned value. For example, you could store it in a variable:

boldtext = Bold("This is a test.");

Because JavaScript considers a function call to be an expression, you can also use it anywhere that type of data (in this case, a string) is expected. For example, you could print it directly:

document.write(Bold("This is a test."));

In this case, the Bold() function is called to produce a result, and the resulting string is used as the parameter of the document.write() function. JavaScript always evaluates expressions like this starting at the innermost level of parentheses.

One final note: You don't actually have to use the value a function returns unless you want to. For example, you have already looked at the eval() built-in function, which executes JavaScript commands from a string. The eval() function returns the result of the commands, but if you don't need to use the result, you can ignore it by simply using a normal function call:

eval("temp = 12");

Integrating Functions with HTML

You should now understand the basics of JavaScript functions and be able to use them in your own programs. At this point, let's look at the best ways of including functions in an HTML document.

First, you should understand one thing: When you declare a function (with the function keyword) the JavaScript interpreter stores it and prepares it for use-but it is not executed. No function is executed until a function call is made for it.

An HTML document consists of two main sections: the header section, contained within the <HEAD> tags, and the body section, contained within <BODY> tags. You can include JavaScript commands and functions in either section.

By convention, the proper place to define a function is in the <HEAD> section. The main reason for this is that browsers do not attempt to display any of the information in this section, so it makes it easy to keep your Web page compatible with older browsers.

Note
Another method of hiding JavaScript from older browsers is discussed in Chapter 1 "Creating Simple JavaScript Programs."

Another reason to include function definitions in the header is that it is the first part of the HTML document loaded by the browser. This will ensure that when you make the function call, the function is loaded and ready to execute. You cannot call a function that hasn't been defined yet.

The function call, on the other hand, should be included in the <BODY> of the HTML document so that it can display its results. As an example, Listing 3.4 shows an HTML document that includes the PrintRow function, defined in Listing 3.2, and uses calls to the function in the body to display a table.


Listing 3.4. (TABLE.htm) An HTML document that uses JavaScript to print a table.
<HTML>
<HEAD>
<TITLE>JavaScript table test</TITLE>
<SCRIPT language="JAVASCRIPT">
function PrintRow(name, age, birthday) {
   document.write("<TR> <TD>", name, "</TD> <TD>", age, "</TD> <TD>", birthday,
 "</TD> </TR>\n");
}
</SCRIPT>
</HEAD>
<BODY>
<H1>Table Test Using JavaScript</H1>
<TABLE>
<SCRIPT language="JAVASCRIPT">
PrintRow("Fred", 27, "June 17");
PrintRow("Tom", 24, "March 13");
PrintRow("Rebecca", 25, "November 30");
</SCRIPT>
</TABLE>
End of table.
</HTML>

As you can see, the PrintRow function is defined in the <HEAD> section of the document and called where it is needed, in the <TABLE> tags in the document's body. You can see the output of this document, as displayed by Netscape, in Figure 3.1.

Figure 3.1 : Netscape displays the output of the JavaScript table example.

Tip
You may not even need a <SCRIPT> tag to call your function. Functions can also be used by event handlers to respond to events. You will explore event handlers in detail in the Event Handlers section, later in this chapter.

Dividing a Task into Functions

At this point, you should understand the purpose of functions. As you move into more complicated JavaScript programming, you will find there are very few tasks you can do without using at least one function, and splitting a task into functions makes it easy to understand.

When you are writing JavaScript, you may not know exactly what should be a function and what shouldn't. Here are some tips for determining whether you should use a function:

In general, any time you end up with more than five to six lines of code, you may want to split parts of it into functions. This makes the main body of code easier to read. As a matter of fact, many programmers use functions almost exclusively, making the main program itself small and very easy to understand.

Communication Between Functions

As you create a large JavaScript program with several functions, you may wonder how the functions will work together. There are two ways to keep track of data between functions.

The first method of passing data to and from a function is the one you've already used-function parameters. You can pass a set of parameters to the function, and the function can return a value.

Although this parameter-passing mechanism works well in most cases, you will run into some situations where it just isn't practical. One reason for this is that functions can return only one value. In cases like this, the answer is to use a variable.

As you learned in Chapter 2 variables you declare in a function with the var keyword are local to that function; they can't be accessed from any other function. In order to keep data between functions, you need to use a global variable.

Defining a global variable is easy: just place the variable definition outside any functions. Once you've defined it, you can then use it in all functions in your program. You can also use global variables in statements outside of functions and in event handlers.

This technique is particularly useful for quantities that concern the whole program. For example, in a game program you might use a global variable for the score. This would enable you to add to the score from any function, without having to pass it back and forth.

Understanding Methods

Now that you understand functions, let's look at how they work with objects. You use a function to define an object, and you can also define methods, or built-in ways of working with the objects.

Methods are simply functions that have been linked to an object and work on the properties of that object. As an example, the built-in string object includes some methods to work with strings. One of them, toLowerCase(), converts the string to all lowercase.

To call a method, you use a period to divide the string name and the method name, as with properties. However, because a method is a function, you must include parentheses for the parameters. In the case of the toLowerCase() method, there are no parameters. The following JavaScript code demonstrates the use of this method:

var text = "THIS IS UPPERCASE";
var ltext = text.toLowerCase();

In this example, the ltext variable is used to hold the lowercase version of the text string. The toLowerCase() method does not modify the string itself; instead, it returns a lowercase version.

Defining Objects and Methods

To further illustrate methods and objects, let's return to the business card example. As you may recall, the Card object you worked with earlier has the following properties:

To define and use this object in a JavaScript program, you need to create a function to create new Card objects. This function is referred to as the object definition for an object, or the constructor. Here is an object definition for the Card object:

function Card(name,address,work,home) {
   this.name = name;
   this.address = address;
   this.work_phone = work;
   this.home_phone = home;
}

The object definition is a simple function that accepts parameters to initialize a new object and assigns those to the corresponding properties. One thing you haven't seen before is the this keyword; this is required for object definitions and refers to the current object-the one that is being created by the function.

Next, let's create a method to work with the Card object. Because all Card objects will have the same properties, it might be handy to have a function that prints the properties out in a neat format. Let's call this function PrintCard().

Because your PrintCard() function will be used as a method for Card objects, you don't need to ask for parameters. Instead, you can use the this keyword again to refer to the current object's properties. Here is a function definition for the PrintCard() function:

function PrintCard() {
   document.write("Name: ", this.name, "\n");
   document.write("Address: ", this.address, "\n");
   document.write("Work Phone: ", this.work_phone, "\n");
   document.write("Home Phone: ", this.home_phone, "\n");
}

This function simply reads the properties from the current object (this), prints each one with a caption, and skips to a new line. The last thing you need to do is make PrintCard() part of the function definition for Card objects. Here is the modified function definition:

function Card(name,address,work,home) {
   this.name = name;
   this.address = address;
   this.work_phone = work;
   this.home_phone = home;
   this.PrintCard = PrintCard;

}

The added statement looks just like another property definition, but it refers to the PrintCard() function. This will work so long as the PrintCard() function is defined with its own function definition.

Creating Instances of Objects

Now let's try using the object definition and method. In order to use an object definition, you create a new object. This is done with the new keyword. The following statement creates a new Card object called tom:

tom = new Card("Tom Jones", "123 Elm Street", "555-1234", "555-9876");

As you can see, creating an object is easy. All you do is call the Card() function (the object definition) and give it the required attributes, in the same order as the definition.

Once this statement executes, a new object is created to hold Tom's information. This is called an instance of the Card object; just as there can be several string variables in a program, there can be several instances of an object you define.

Now that you've created an instance of the card object, you can use the PrintCard() method to print it out:

tom.PrintCard();

Putting It All Together

Now you've created a new object to store business cards and a method to print them out. As a final demonstration of objects, properties, functions, and methods, let's use this object in a Web page to print data for several cards.

The HTML document will need to include the function definition for PrintCard() along with the function definition for the Card object. You will then create three cards and print them out in the body of the document. Listing 3.5 shows the complete HTML document.


Listing 3.5. (ADDRESS.htm) An HTML document that uses the Card object.
<HTML>
<HEAD>
<TITLE>JavaScript Business Cards</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function PrintCard() {
   document.write("<B>Name:</B> ", this.name, "<BR>");
   document.write("<B>Address:</B> ", this.address, "<BR>");
   document.write("<B>Work Phone:</B> ", this.work_phone, "<BR>");
   document.write("<B>Home Phone:</B> ", this.home_phone, "<HR>");
}
function Card(name,address,work,home) {
   this.name = name;
   this.address = address;
   this.work_phone = work;
   this.home_phone = home;
   this.PrintCard = PrintCard;
}
</SCRIPT>
</HEAD>
<BODY>
<H1>JavaScript Business Card Test</H1>
Script begins here.<HR>
<SCRIPT LANGUAGE="JavaScript">
// Create the objects
sue = new Card("Sue Suthers", "123 Elm Street", "555-1234", "555-9876");
phred = new Card("Phred Madsen", "233 Oak Lane", "555-2222", "555-4444");
henry = new Card("Henry Tillman", "233 Walnut Circle", "555-1299", "555-1344");
// And print them
sue.PrintCard();
phred.PrintCard();
henry.PrintCard();
</SCRIPT>
End of script.
</BODY>
</HTML>

Notice that I have modified the PrintCard() function slightly to make things look good with HTML line breaks, boldface, and horizontal rules. The Netscape output of this document is shown in Figure 3.2.

Figure 3.2 : Netscape displays the output of the business card example.

Conditionals and Loops

Next, let's look at two types of statements you'll need in just about any large program: conditionals, which enable you to test data, and loops, which execute a block of code multiple times.

The if...else Construct

The if statement is the main conditional statement in JavaScript. You can use it to check for certain values and act accordingly. You will find that just about every large program uses conditionals, whether to act on data the user enters or to check for errors. Here is an example of a basic if statement:

if (a == 1) document.write("Found a 1!");

This statement checks the variable a, and if it has a value of 1, prints a message. Otherwise, it does nothing. You can also use multiple statements by enclosing them in braces:

if (a == 1) {
   document.write("Found a 1!");
   a = 0;
}

This block of statements checks the variable a once again. If it finds a value of 1, it prints a message and sets a back to zero.

The if statement has an optional else keyword, which can specify a block of statements to execute if the condition is not true. You could modify Listing 3.5 to print an alternative message if the value of a is not 1:

if (a == 1) {
   document.write("Found a 1!");
   a = 0;
}
else {
   document.write("Incorrect value: " + a);
   a = 0;
}

As you can see, you can follow the block of statements after the if keyword with an else keyword and a second block of statements. Only one of the blocks will be executed, depending on the condition.

You can use any of the conditional expressions and operators introduced in Chapter 2as the conditional in the if statement. You can also use a nonconditional expression, such as a variable assignment; the condition will be true if the assignment is successful.

Note
One of the most common errors is to use the assignment (=) operator in a conditional instead of the equality (==) operator. This can be especially confusing because the assignment will evaluate as a true condition. Be sure to check your conditions for this.

Conditional Expressions

In addition to the if statement, JavaScript provides a shorthand type of conditional expression that you can use to make quick decisions. This uses a peculiar syntax, which is also found in other languages, such as C. Here is an example of a conditional expression:

value = (a == 1) ? 1: 0;

This statement may look confusing, but it is equivalent to this if statement:

if (a == 1)
   value = 1;
else
   value = 0;

In other words, the value after the question mark (?) will be used if the condition is true, and the value after the colon (:) will be used if the condition is false. The colon represents the else portion of the statement, and like the else portion of the if statement, is optional.

These shorthand expressions can be used anywhere JavaScript is expecting a value. They provide an easy way to make simple decisions about values. As an example, here's an easy way to display a grammatically correct message about the counter variable:

document.write("Found ", counter, (counter == 1) ? " word.": " words.");

This will print the message "Found 1 word" if the counter has a value of 1, and "Found 2 words" with a value of 2 or greater. This is one of the most common uses for a conditional expression.

Using the for Keyword

One of the main reasons for computer programs is to perform repetitive tasks. JavaScript includes several keywords that make it easy to repeat blocks of code in a loop. There are several different types of loops, each with its own keyword.

The for keyword is the first tool to look at for creating loops. A for loop typically uses a variable (called a counter or index) to keep track of how many times the loop has executed, and it stops when the counter reaches a certain number. A basic for statement looks like this:

for (var = 1; var < 10; var++) {

There are three parameters to the for loop, separated by semicolons:

After the three parameters are specified, a left brace is used to signal the beginning of a block. All the statements between the braces will be executed with each iteration of the loop.

This may sound a bit confusing, but once you're used to it, you'll use for loops frequently. Let's take a look at a simple example of this type of loop, shown in Listing 3.6.


Listing 3.6. A loop using the for keyword.
for (i=1; i<10; i++) {
   document.write("This is line ",i,"\n");
}

This example displays a message including the loop's counter during each iteration. The output of Listing 3.6 would look like this:

This is line 1
This is line 2
This is line 3
This is line 4
This is line 5
This is line 6
This is line 7
This is line 8
This is line 9

Notice that the loop was executed only nine times. This is because i<10 is the conditional. When the counter (i) is incremented to 10, the expression is no longer true. If you need the loop to count to 10, you could change the conditional; either i<=10 or i<11 will work fine.

Note
You might notice that the variable name i is often used as the counter in loops. This is a programming tradition that began with an ancient language called Fortran. There's no need for you to follow this tradition, but it is a good idea to use one consistent variable for counters.

The structure of the for loop in JavaScript is based on Java, which in turn is based on C. Although it is traditionally used to count from one number to another, you can use just about any statement for the initialization, condition, and increment. However, there's usually a better way to do other types of loops with the while keyword, described in the next section.

Using while Loops

The other keyword for loops in JavaScript is while. Unlike for loops, while loops don't necessarily use a variable to count. Instead, they execute as long as (while) a condition is true. In fact, if the condition starts out as false, the statements might not execute at all.

The while statement includes the condition in parentheses, and it is followed by a block of statements within braces, just like a for loop. As an example, here is a simple while loop:

while (total < 10) {
n++;
total += values[n];
}

This loop uses a counter, n, to iterate through the values array. Rather than stopping at a certain count, however, it stops when the total of the values reaches 10.

You might have noticed that you could have done the same thing with a for loop:

for (n=0;total < 10; n++) {
total += values[n];

}

As a matter of fact, the for loop is nothing more than a special kind of while loop that handles an initialization and an increment for you. You can generally use while for any loop; however, it's best to choose whichever type of loop makes the most sense for the job, or takes the least amount of typing.

The for...in Construct

There's a third type of loop available in JavaScript. The for...in loop is not as flexible as ordinary for or while loops; instead, it is specifically designed to perform an operation on each property of an object.

For example, remember that the elements of an array are actually properties of an array object. You can use a for...in loop to access each element of the array in turn. This simple loop adds one to each of the members of the counters array:

for (i in counters) {
counters[i]++;

}

Like an ordinary for loop, this type of loop uses an index variable. (i in the example). For each iteration of the loop, the variable is set to the next property of the object. This makes it easy when you need to check or modify each of an object's properties.

Remember that this doesn't just work with arrays-the previous example would work with an array with indices 1 through 5, but it would also work if the object had properties such as hits and misses. The index variable would be set to each of the property names.

Infinite Loops

The for and while loops allow you quite a bit of control over the loop. In some cases, this can cause problems if you're not careful. Take this loop, for example:

while (j < 10) {
n++;
values[n] = 0;
}

I've made a mistake in the previous example. The condition of the while loop refers to the j variable, but that variable doesn't actually change during the loop. This creates an infinite loop. The loop will continue executing until it is stopped by the user, or until it generates an error of some kind.

Obviously, infinite loops are something to avoid. They can also be difficult to spot, because JavaScript won't give you an error that actually tells you there is an infinite loop. Thus, each time you create a loop in your JavaScript programs, you should be careful to make sure there's a way out.

Occasionally, you may want to create an infinite loop deliberately. This might include situations when you want your program to execute until the user stops it or if you are providing an escape route with the break statement, introduced below. Here's an easy way to create an infinite loop:

while (true) {

Because the value true is the conditional, this loop will always find its condition to be true.

The break Statement

There is one way out of an infinite loop. The break statement can be used during a loop to exit the loop immediately and continue with the first statement after the loop:

while (true) {
n++;
if (values[n] == 1) break;
}

Although the while statement is set up as an infinite loop, the if statement checks the corresponding value of an array, and if it finds a 1, it exits the loop.

When a break statement occurs, the rest of the loop is skipped, and execution continues with the first statement after the loop's ending right brace. You can use the break statement in any type of loop, whether infinite or not. This provides an easy way to exit if an error occurs, or if you've found what you're looking for.

The continue Statement

One more statement is available to help you control the execution of statements in a loop. The continue statement skips the rest of the loop, but unlike break, it continues with the next iteration of the loop:

for (i=1; i<21; i++) {
if (score[i]==0) continue;
document.write("Student number ",i, " Score: ", score[i], "\n");
}

This program uses a for loop to print out scores for 20 students, stored in the score array. The if statement is used to check for 0 scores. You assume that a score of 0 means that the student didn't take the test, so you continue the loop without printing the score.

Using Multiple Parameters in Functions

As a practical example of looping, let's look at a program that deals with multiple values in an array. When dividing your program into functions, you may run into a need for a function that can accept a variable number of parameters. For example, imagine a Total() function that would add together all the parameters it receives. You could call it using these statements:

a = Total(2,3,4);
document.write(Total(a, 17));
b = Total (a, b, c, d, e);

To return the correct result in all of these cases, the Total() function needs to accept a variable number of parameters. JavaScript supports multiple-parameter functions through a special array, arguments, which is a property of the function. You can define a function without a parameter list, then use this array to read the parameters.

Using this feature, you can easily create the Total() function:

function Total() {
   var tot = 0;
   for (i=0;i<Total.arguments.length;i++) {
      tot += Total.arguments[i];
   }
   return tot;

}

You use a for loop to read all the arguments. The arguments.length property gives us the total number of arguments. Each is added to the local tot variable, which is returned.

Events and Event Handlers

The final concept you will look at in this chapter is one of the strengths of JavaScript: event handlers. These enable you to integrate JavaScript with a Web page in ways possible with no other language.

In an object-oriented environment, events are often used to trigger portions of a program. In JavaScript, events pertain to the Web page containing the script. When the user clicks on a link, selects or enters text, or even moves the mouse over part of the page, an event occurs.

You can use JavaScript to respond to these events. For example, you can have custom messages displayed in the status line (or somewhere else on the page) as the user moves the mouse over links. You can also update fields in a form whenever another field changes.

Note
Because one of the main uses for event handlers is in HTML forms, you will explore them in much more detail in Chapter 6 "Using Interactive Forms."

Types of Events

You will explore the different events available for use in JavaScript, and the objects they correspond with, in Chapter 5 "Accessing Window Elements as Objects." For now, take a quick look at Table 3.1, which lists the types of events and their use.

Table 3.1. Available events in JavaScript.

Event NameDescription
onAbort Occurs when the user aborts the loading of an image
onBlur Occurs when an object on the page loses focus
onChange Occurs when a text field is changed by the user
onClick Occurs when the user clicks on an item
onError Occurs when a document or image can't load correctly
onFocus Occurs when an item gains focus
onLoad Occurs when the page (or an image) finishes loading
onMouseOver Occurs when the mouse pointer moves over an item
onMouseOut Occurs when the mouse pointer moves off an item
onSelect Occurs when the user selects text in a text area
OnSubmit Occurs when a submit button is pressed
OnUnload Occurs when the user leaves the document or exits

As you can see, you can respond to a wide variety of events. This makes it possible to interact with the user instantaneously-something CGI programmers have wanted for years.

Creating an Event Handler

Event handlers are not defined with <SCRIPT> tags. Instead, they are an attribute of individual HTML tags. For example, here is a link that includes an event handler:

<A HREF="http://www.starlingtech.com/books/javascript/"
   onMouseOver="window.status='An amazingly useful link'; return true">
Click here</A>

Note that this is all one <A> tag, although it's split into multiple lines. This specifies two statements to be used as the onMouseOver event handler for the link. The first statement displays a message in the status bar; the second returns a true value to keep the message from being erased.

Note
The previous example uses single quotation marks to surround the text. This is necessary in an event handler, because double quotation marks are used by HTML. The event handler itself is surrounded by double quotes.

You can use JavaScript statements like the previous one in an event handler, but if you need more than one statement, it's a good idea to use a function instead. Just define the function in the <HEAD> of the document, then call the function as the event handler:

<a href="#bottom" onMouseOver="DoIt();">Move to the bottom</A>

This example calls the DoIt() function when the user moves the mouse over the link. Using a function is convenient because you can use longer, more readable JavaScript routines as event handlers.

How Event Handlers Interact

As a final note about event handlers, you need to know a bit of programming philosophy. If you've programmed in a language such as BASIC, C, or Perl, you're used to creating a program that executes in a logical order, and you control that order.

With graphical environments, such as Windows and the Macintosh, came the need for event-based programming. This type of programming uses events to trigger sections of the program, so you don't really know what order it will execute in-that depends on what the user does.

On the other hand, event-based programming can make things much easier. In traditional programming, you typically interact with the user with a series of if statements, checking for each thing the user might have done. In event-based programming, this part is done for you-all you have to do is write the functions for each event you wish to handle.

If you've programmed in other environments, the event-based nature of JavaScript might take a bit of getting used to, but it's worth it-it makes programming simple. If JavaScript is the first language you're learning, you'll find it easy to learn to use events. Event handlers are used in several useful ways in Chapter 5and throughout this book.

Workshop Wrap-Up

In this chapter, you learned many of the more advanced aspects of JavaScript, including the following:

Next Steps

Next, you can learn more about objects in JavaScript, or move on to creating more complex programs:

Q&A

Q:
There are many books that go into more complicated detail about object-oriented programming. Do these apply to JavaScript?
A:
Only partially. JavaScript uses a basic implementation of objects, and does not fully support features, such as encapsulation and inheritance, which are considered traits of "true" objects. JavaScript's objects are simple, and you should learn all you need to know about them in this book.
Q:
Some languages, such as C, have a switch or case statement, which enables me to test several conditions conveniently. Does JavaScript have anything like this?
A:
Not exactly. You can use a sequence of if and else if statements to do the same thing, though.
Q:
If I use the onSelect method, how can I tell what part of the text was selected?
A:
Unfortunately, you can't. This may be resolved in a future version of JavaScript. Even then, writing a complete text editor in JavaScript may be a bit ambitious.