JavaScript 101 - Part 2
About the Author
Kevin Yank
Kevin began developing for the Web in 1995 and is a highly respected technical author. He wrote Build your own Database Driven Website using PHP and MySQL, a practical step-by-step guide published by SitePoint, and he's co-author of the SitePoint Tech Times, a bi-weekly newsletter for technically-minded web developers. Kev believes that any good webmaster should have seen at least one episode of MacGyver.
By: Kevin Yank
June 25th, 2001
This article was originally published by Sausage Software [1], makers of the HotDog Professional Web Editor. Reprinted here by permission.
Hey there, and welcome back! Last time [2], we took a whirlwind tour of the basics of JavaScript. We looked at statements, variables, control structures, and functions, learning what they were and how they were used. Armed with those concepts and a couple of built-in functions, we wrote a script to allow us to automatically create alternating table row colors.
In Part II, we'll flesh out our knowledge a bit by looking at a few new concepts: arrays, event handlers, and the document object model. We'll then apply these in a few practical examples that you'll be able to use in your own Web pages.
Since we'll be picking up precisely where we left off last time, you shouldn't have any trouble following along if you've come this far. The preliminaries are out of the way, so let's jump right in!
Arrays
As you begin to experiment with writing your own JavaScript, you may encounter a situation where you'd like to store a list of values. For example, you might like to work with the monthly revenue history of your company. Now, you could create a bunch of variables called revenue_month_year, but working with so many variables in an organised way would be pretty inconvenient.
Arrays offer a way of grouping such lists of data into a single variable. To illustrate, let's look at how to create an array containing the days of the week:
var days = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
The above code creates a new variable called days, an array containing seven text strings (the days of the week, in order). To access a particular value from an array, you follow the name of the array with square brackets containing the index of the value you want. The index of the first value in an array is 0, the index of the second is 1, and so on. So the following code will display the message "I can't believe I have to work on Sunday!":
alert( "I can't believe I have to work on " + days[0] + "!");
Arrays also keep track of the number of values stored inside them. This value can be accessed as arrayName.length. So the following code displays the message "There are 7 days in the week.":
alert( "There are " + days.length + " days in the week.");
Each value in an array acts just like a normal variable, which means you can update the stored values just as you would any normal variable. This allows you to create an array even though some or all of the values you want to store in it may not yet be available. To create an array of a given length but without any actual values stored in it, you use a different form of the new Array(...) syntax. Here's an alternate method to create the days array above that illustrates this:
var days = new Array(7);
days[0] = "Sunday";
days[1] = "Monday";
days[2] = "Tuesday";
days[3] = "Wednesday";
days[4] = "Thursday";
days[5] = "Friday";
days[6] = "Saturday";
A little longer, but in some situations, this can be more convenient. Notice that we specified the desired size of the array (new Array(7)).
Okay, so arrays are kinda neat, but they don't seem particularly useful yet, do they? Before we look at an example that's more interesting, we need to learn a new control structure.
In Part 1 [3], we looked at the if and if-else control structures. These allowed you to choose whether or not to execute a piece of code (or choose between two pieces of code) based on some condition. Another control structure, called a for loop allows you to keep executing a piece of code over and over as long as some condition is true. This action of repeating the same code over and over is called looping. The general form of a for loop is as follows:
for (setup-statement; loop-condition; loop-update) {
...code to run each time through the loop...
}
setup-statement should be a command that gets run once before anything else happens. This is usually used to create and initialize a variable to count the number of times the loop has executed. loop-condition is a condition just like the condition in the if/if-else control structures. The condition is checked each time through the loop, before the code between the braces is run. If the condition is true, the code between the braces will be executed. If the condition is false, the for loop ends and execution continues following the closing brace. loop-update is a command that is run right after the code between braces and before the condition is checked for the next time through the loop.
The best way to explain how a for loop works is with a simple example. Consider the following code:
for (var i = 1; i <= 3; i++) {
document.write(i + "<br>");
}
You should remember the document.write function from Part 1 [4], which just writes what it is given into the HTML document. i++ is a shortcut for i = i + 1. The above code will write numbers 1 through 3 with <br> tags following them so they appear on separate lines. Here's how the for loop works in this case:
setup-statement: |
Create a variable |
loop-condition: |
|
loop code: |
|
loop-update: |
i = 2; |
loop-condition: |
|
loop code: |
document.write("2 |
loop-update: |
i = 3; |
loop-condition: |
|
loop code: |
document.write("3 |
loop-update: |
i = 4; |
loop-condition: |
|
(loop ends) | |
So what does all this have to do with arrays? Returning to our previous example, let's say you want to have a table on your Web page containing a history of monthly revenues for your company. You could write the table entirely in HTML, but using a JavaScript array to store the values would be more efficient. Instead of having to make updates to the HTML code, you could just change the figures in the array and the HTML would take care of itself. What's more, you could display a "total year to date" revenue figure at the bottom of the table that would be calculated and kept up-to-date by JavaScript using the values in your array. Here's the relevant code:
<script language="JavaScript">
<!--
// Create two arrays: one to store the names of the months,
// and one to store the revenues for those months.
var months = new Array("January", "February",
"March", "April");
var revenues = new Array(12000, 9560, 11298, 12151);
//-->
</script>
<table border="1">
<tr><th>Month</th><th>Revenue (thousands of $)</th></tr>
<script language="JavaScript">
<!--
// Use a for loop to step through the two arrays and print
// the values in the table.
for (var i=0; i<months.length; i++) {
document.write("<tr><td>" + months[i] + "</td>");
document.write("<td>$" + revenues[i] + "</td></tr>");
}
//-->
</script>
</table>
<script language="JavaScript">
<!--
// Calculate the total revenue so far and display it
var totalRevenue = 0;
for (var i=0; i<months.length; i++) {
totalRevenue = totalRevenue + revenues[i];
}
document.write("Total Year to Date: $" + totalRevenue);
//-->
</script>
There are three pieces of JavaScript in the above code. The first creates the arrays to hold the names of the months and the revenue figures. The second writes the body of the table by using a for loop. The trick here is that in the code inside the loop, i is used to specify the index in our two arrays. The for loop starts with i equal to 0, then counts up until i equals the length of the months array, at which point the loop ends. The third piece of JavaScript works very similarly, but instead of printing the revenue values using document.write, it adds them all to totalRevenue, which is then used to print out the total!
Don't believe your eyes? Here's the output of the above code:
| Month | Revenue (thousands of $) |
|---|
If you're feeling ambitious, here's a challenge for you. Combine this example with the example given in Part 1 [5] to give this table of revenues alternating row colors!
The Document Object Model
Before I can adequately explain what the Document Object Model is, you must first become familiar with a few basic concepts to do with objects.
You can think of an object as a variable that stores a state instead of a simple value. That state is reflected in the values of one or more properties. Take the arrays we just looked at, for example. An array is an example of an object. It stores a set of values, and maintains a property called length that reflects the state of the array (the number of values it contains). You access the value of the property by taking the name of the object and adding the name of the property to the end (separated by a period):
objectName.propertyName –> myArray.length
The Document Object Model (DOM for short) is a set of objects that the Web browser creates for you. Those objects and their properties reflect the browser, the currently-loaded document, and various other information. Using the DOM, it is possible for your script to access information about the Web browser it is running in and the document that is currently loaded, and even make changes to that information!
Consider the following JavaScript code:
<script language="JavaScript">
<!--
document.write("The browser you are running is " +
navigator.appName + ".");
//-->
</script>
This shouldn't be too unfamiliar. It's just using document.write to print something into the current Web page. Look at the hilighted code, however. navigator.appName refers to the appName property of the navigator object, but nowhere in our code did we create such an object. Nevertheless, that object exists as part of the DOM, and represents the Web browser itself. The values of its properties are set automatically by the browser in which the script happens to be running at the time. For example, on your browser the above code produces the following output:
One example of using the DOM to actually alter the document that we've already seen is the so-called document.write built-in function that we just used. In addition to having values called properties, objects may have functions called methods. When invoked, those functions perform some operation related to the object. When you call document.write, you are actually invoking the write method of the document object, which exists as part of the DOM, and represents the current HTML document.
objectName.methodName(parameters) –> document.write("...")
The DOM is an extensive collection of objects, properties, and methods, and different Web browsers support slightly different DOM's (although most have basic things like document.write and navigator.appName). In his book, Dynamic HTML: The Definitive Reference [6], Danny Goodman presents a complete reference to the DOM's supported by Netscape Navigator and Internet Explorer browsers up to and including versions 4.0. That reference is nearly 400 pages long! As you can see, a complete presentation of the DOM and its capabilities is far beyond the scope of this tutorial, but knowing the concepts we have just presented will allow you to grasp how the examples in the rest of this article work.
A popular (if sometimes annoying) feature of the DOM is its support for creating pop-up windows. More sophisticated than adding target="_blank" to links, JavaScript pop-up windows allow you to specify the size and what features appear in the new browser window.
Creating a JavaScript pop-up window is as easy as invoking the open method of the DOM window object. The syntax of this method is as follows:
window.open(URL, windowName, windowFeatures)
URL is just a text string containing the address of the file to be loaded into the pop-up window. This works just like the href attribute of a standard link tag. windowName is also a text string, and is used to give a name to the pop-up window. This name is never actually displayed, but if you try to open another pop-up window with the same name, the browser will instead load the file into the existing pop-up window. You can also use the name of a window in the target attribute of normal a href tags to have those links load in the pop-up window once it has been created.
The windowFeatures parameter is also a string. It allows you to specify details about the window. In addition to setting the width and height of the window, you also need to list all features that you want the new window to contain. Here's a list of the features supported by both Microsoft Internet Explorer and Netscape Navigator:
- copyhistory The URL history of the current window (i.e. the set of pages accessible with the "back" and "forward" buttons) is copied to the new window.
- directories The "directory buttons" are available in the new window.
- location The URL field is displayed in the new window.
- menubar The menu bar is displayed in the new window.
- resizable The new window may be resized.
- scrollbars If the document is too large to fit in the window, scrollbars will be displayed.
- status The status bar is displayed at the bottom of the new window.
- toolbar The main button bar, with the "back" and "forward" buttons, is displayed in the new window.
The features you want the new window to posess should be listed, separated by commas (no spaces). Features not in the list will not appear in the pop-up window. If you list no features at all by only specifying the URL and window name, the window will be created with the standard elements, as configured in your browser. So, for example, to load popup.html into a resizable pop-up window 400 pixels wide and 300 pixels high with a status bar, a menu bar, and scrollbars as needed, you would use the following code:
window.open("popup.html", "popupwindow", "width=400,height=300,resizable,status,menubar,scrollbars");
Since most of the time you'll want to attach a popup window to a link, you'll need to know how to execute some JavaScript in response to a link being clicked. This sort of thing is best accomplished using event handlers, which we'll discuss next. But for the time being, here's a simple way to do it:
<script language="JavaScript">
<!--
function showpopup() {
var popwin = window.open("popup.html", "popupwindow",
"width=400,height=300,resizable,status,menubar,scrollbars");
popwin.focus();
}
//-->
</script>
<a href="javascript:showpopup()">Click for a pop-up window!</a>
The showpopup function we've defined here starts by calling window.open, and appears to assign this method as a value to a new variable called popupwin. In fact, the window.open method returns a reference to the window object for the newly-created window (as opposed to the window object for the current window). popupwin is therefore another window object. We use this on the next line by calling its focus method, which brings the new window to the foreground. This ensures that if a window named popupwindow existed prior to this link being clicked (for example, if the link were clicked twice in succession), the window in question would be made the active window after popup.html was loaded into it.
The following is a link created with the exact code given above:
Event Handlers
Aside from the little pop-up window link we just looked at, all the scripts we've seen so far have had one thing in common: they ran as the page containing them was loading. Where things really get interesting is when JavaScript code can run in response to actions the user takes after the page has loaded. This opens up possibilities for back-and-forth interaction with the user beyond scrolling up and down and looking at a static Web page.
Event handlers allow you to set snippets of HTML code to be run in response to some event, be it something the user does (like clicking on a link), or something that happens in the browser (like the page loading completing). To illustrate, let's enhance the JavaScript pop-up link that we created in the previous section. Instead of triggering the showpopup function using the special JavaScript form of the href attribute as we did before, we'll use the onClick event handler:
<a href="popup.html" onClick="showpopup();return false;">Click for a popup</a>
In the above, the onClick attribute of the a href tag is an event handler. Specifically, it is an event handler that handles the "click" event, which occurs whenever the user clicks on the link. The attribute specifies the JavaScript code to be run when this event occurs. First, it calls the showpopup function, and then it returns a value of false.
"Returning a value" is a fancy way of saying "generating a result". When the result of a "click" event handler is false, the browser will ignore that click instead of responding to it as it normally would. In the case of our link here, the normal browser response would be to load the document given in the href attribute into the current browser window or frame. By returning false in our event handler, we are telling the browser that our event handler has done everything that needs doing in response to the click, and it shouldn't bother loading that document (since we've already loaded it into a pop-up window ourselves).
So what's the point of the href attribute in the above? It's there for browsers that don't support JavaScript, or that have JavaScript disabled. Such browsers will ignore the event handler attribute and will just see a normal link to popup.html. This provides a good fallback measure for older browsers, without interfering with the pop-up window that newer browsers will display.
Another simple example of using event handlers is to display descriptions of links in the browser status bar when the mouse moves over them. Here's the code for such a link:
<a href="target.html" onMouseOver="window.status='Link description'; return true;" onMouseOut="window.status=''; return true;">...</a>
This code uses two event handlers: onMouseOver, which reacts to the mouse moving onto the link, and onMouseOut, which reacts to the mouse moving off of the link. Both of these event handlers have been set to change the status property of the DOM window object (which corresponds to the text appearing in the status bar of the current window), then return true.
Returning true here performs the same function as returning false in our pop-up link above did. It tells the browser "don't do whatever you would normally do", which in the case of moving the mouse over a link would be to display the link target URL in the status bar. We want to tell the browser not to do this, because it would write over the description we just placed there. Why returning false stops a "click" event from having its usual effect and returning true stops "mouseover" and "mouseout" events from having their usual effects is anybody's guess. Some silly person decided that made sense at some point and that's the way it's been ever since.
Here's a link that displays a status bar message for you to try out:
Summary and Further Reading
In this, the second part of our series, we played with a few more subtle features of JavaScript: arrays, the Document Object Model (DOM), and event handlers. For each of these, we began by learning what it was, then played with a practical application of the concept.
By now you should be starting to have an appreciation of what JavaScript is capable of, even if we haven't had time to describe every object in the DOM, or every event handler supported by current browsers. Grasping these concepts is really the toughest part of learning a new language like JavaScript. The rest is just a matter of getting a hold of a good reference.
Next Time
In Part 3 [9], we'll have a close look at using JavaScript in combination with HTML forms. Among other things, we'll look at how we can validate information that a user has entered into a form before sending that data to the Web server.
[1] http://www.sausagetools.com
[2] /article.php/452
[3] /article.php/452
[4] /article.php/452
[5] /article.php/452/
[6] http://amazon.com/exec/obidos/ASIN/1565924940/webmasterresou05/
[7] javascript:showpopup()
[8] javascript:void(0)
[9] http://webmasterbase.com/article/455