JavaScript: The Brains of Your Page - Appendixes - HTML5: The Missing Manual Matthew MacDonald (2013)

HTML5: The Missing Manual Matthew MacDonald (2013)

Part 4. Appendixes

Appendix B. JavaScript: The Brains of Your Page

There was a time when the Web was all about markup. Pages held text and HTML tags, and not much more. Really advanced websites used server scripts that could tweak the HTML markup before it made its way to the browser, but the code stopped there.

Crack open a web page today and you’re likely to find buckets of JavaScript code, powering everything from vital features to minor frills. Self-completing text boxes, pop-up menus, slideshows, real-time mapping, and webmail are just a few examples of the many ways crafty developers put JavaScript to work. In fact, it’s nearly impossible to imagine a Web without JavaScript. While HTML is still the language of the Web, JavaScript is now the brains behind its most advanced pages.

In this appendix, you’ll get a heavily condensed JavaScript crash course. This appendix won’t provide a complete tutorial on JavaScript, nor does it have enough information to help you get started if you’ve never written a line of code in any programming language, ever. But if you have some rudimentary programming knowledge—say, you once learned a lick of Visual Basic, picked up the basics of Pascal, or took C out for spin—this appendix will help you transfer your skills to the JavaScript world. You’ll get just enough information to identify familiar programming ingredients like variables, loops, and conditional logic. And you’ll cover all the basic language elements that are used in the JavaScript-based examples in the rest of this book.

TIP

If you need more help to get started with JavaScript, check out JavaScript & jQuery: The Missing Manual by David Sawyer McFarland, which also introduces jQuery, a popular JavaScript-enhancing toolkit. Or read Mozilla’s detailed JavaScript guide at http://developer.mozilla.org/JavaScript.

How a Web Page Uses JavaScript

Before you can run a line of JavaScript, you need to know where to put it in your web page. It all starts with the <script> element. The following sections show you how to take a page from quick-and-dirty JavaScript injection to a properly structured example that you can put online without embarrassment.

Embedding Script in Your Markup

The simplest way to use the <script> element is to stick it somewhere in your HTML markup, like this:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<title>A Simple JavaScript Example</title>

</head>

<body>

<p>At some point in the processing of this page, a script block

will run and show a message box.</p>

<script>

alert("We interrupt this web page with a special JavaScript announcement.");

</script>

<p>If you get here, you've already seen it.</p>

</body>

</html>

This script block contains just one line of code, although you could just as easily pack it with a sequence of operations. In this case, the single line of code triggers JavaScript’s built-in alert() function. The alert() function accepts a piece of text and shows that text in a message box (seeFigure B-1). To move on, the user must click the OK button.

NOTE

This example introduces a JavaScript convention that you’ll see throughout this book, and on good websites everywhere: the semicolon. In JavaScript, semicolons indicate the end of each programming statement. Strictly speaking, semicolons aren’t necessary (unless you want to cram multiple statements on a single line). However, they’re considered good style.

If you want to run some JavaScript right away (as in this example), you’ll probably put the <script> section at the end of the <body> section, just before the final </body> tag. That way, it runs only after the browser has processed all the page markup.

When the web browser comes across JavaScript code, it runs it immediately. In fact, it even halts the page processing, temporarily. In this case, the code is held up until the web page user closes the message box by clicking OK. This allows the code to continue and the script block to end. The web browser then processes the rest of the markup.

Figure B-1. When the web browser comes across JavaScript code, it runs it immediately. In fact, it even halts the page processing, temporarily. In this case, the code is held up until the web page user closes the message box by clicking OK. This allows the code to continue and the script block to end. The web browser then processes the rest of the markup.

GEM IN THE ROUGH: DEALING WITH INTERNET EXPLORER’S PARANOIA

If you run the alert example above in Firefox or Chrome, you’ll find that everything works seamlessly. If you run it in Internet Explorer, you won’t get the same satisfaction. Instead, you’ll see a security warning in a yellow bar at the top or bottom of the page (depending on the version of IE). Until you go to that bar and click “Allow blocked content,” your JavaScript code won’t run.

At first glance, IE’s security warning seems like a surefire way to scare off the bravest web visitor. But you don’t need to worry; the message is just part of the quirky way Internet Explorer deals with web pages that you store on your hard drive. When you access the same page over the Web, Internet Explorer won’t raise the slightest objection.

That said, the security warning is still an annoyance while you’re testing your web page, because it forces you to keep explicitly telling the browser to allow the page to run JavaScript. To avoid the security notice altogether, you can tell Internet Explorer to pretend you downloaded your page from a web server. You do this by adding a special comment called the mark of the Web. You place this comment in the <head> section of your page:

<head>

<meta charset="utf-8">

<!-- saved from url=(0014)about:internet

-->

...

</head>

When IE sees the mark of the Web, it treats the page as though it came from a web server, skipping the security warning and running your JavaScript code without hesitation. To all other browsers, the mark of the Web just looks like an ordinary HTML comment.

Using a Function

The problem with the previous example is that it encourages you to mingle code and markup in an unseemly mess. To keep things organized, you should wrap each code “task” in a function—a named unit of code that you can call into action whenever you need it.

When you create a function, you should give it a logical name. Here’s a function named showMessage():

function showMessage() {

// Code goes here ...

}

The function body—its guts—includes everything between the opening { bracket and the closing } bracket. Inside these delimiters, a function can hold as many lines of code as you need. Right now, the showMessage() function contains a single line, which is the “Code goes here” comment. (A JavaScript comment is a line that starts with two slash characters. The browser ignores all comments—you add them to remind yourself of important details or inform others about what the code is doing.)

To add some code to your function, just put all the statements you need between the curly brackets:

function showMessage() {

alert("We interrupt this web page with a special JavaScript announcement.");

}

Of course, this whole shebang needs to go in a <script> block. The best place to put JavaScript functions is in the <head> section. This imposes some basic organization on your page, by moving the code out of the markup and into a separate section.

Here’s a revamped version of the earlier example, which now uses a function:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<title>A Simple JavaScript Example</title>

<script>

function showMessage() {

alert("We interrupt this web page with a special JavaScript announcement.");

}

</script>

</head>

...

Functions, on their own, don’t do anything. To trigger a function, you need another piece of code that calls the function.

Calling a function is easy—in fact, you’ve already seen how to do it with the built-in alert() function. You simply write the function name, followed by a set of parentheses. Inside the parentheses, you put whatever data the function needs. Or, if the function doesn’t accept any data, likeshowMessage(), you simply include parentheses with nothing inside them:

...

<body>

<p>At some point in the processing of this page, a script block

will run and show a message box.</p>

<script>

showMessage();

</script>

<p>If you get here, you've already seen it.</p>

</body>

</html>

In this example, the function and the code that calls the function are in separate <script> blocks. This design isn’t necessary, but it’s used here to emphasize the separation between these two pieces.

At first glance, adding a function seems to make this example more complicated than before. But it’s actually a dramatic step forward in design, for several reasons:

§ The bulk of the code is out of the markup. You need just one line of code to call a function. However, a realistic function will contain a pile of code, and a realistic page will contain a pile of functions. You definitely want to separate all those details from your markup.

§ You can reuse your code. Once code is in a function, you can call that function at different times, from different places in your code. This isn’t obvious in this simple example, but it becomes an important factor in more complex applications, like the painting application in Chapter 8.

§ You’re ready to use external script files. Moving your code out of the markup is a precursor to moving it right out of the HTML file, as you’ll see in the next section, for even better organization.

§ You can add events. An event is a way for you to tell the page to run a specific function when a specific occurrence takes place. Web pages are event-driven, which means most code is fired up when an event happens (rather than being launched through a script block). Events pair neatly with functions, as you’ll see on Responding to Events.

Moving the Code to a Script File

Pulling your JavaScript code together into a set of functions is the first step in good organization. The second step is to take that script code and put it in an entirely separate file. Do this with all your scripts, and you’ll get smaller, simpler web pages—and the ability to reuse the same functions in different web pages. In fact, putting script code in an external file is analogous to putting CSS style rules in an external file. In both cases, you gain the ability to reuse your work and you leave simpler pages behind.

NOTE

Virtually every well-designed web page that uses JavaScript puts the code in one or more script files. The only exceptions are if you have a few lines of very simple code that you’re certain not to use anywhere else, or if you’re creating a one-off example.

Script files are always plain text files. Usually, they have the extension .js (which stands for JavaScript). You put all your code inside a script file, but you don’t include the <script> element. For example, here are the complete contents of a script file named MessageScripts.js:

function showMessage() {

alert("We interrupt this web page with a special JavaScript announcement.");

}

Now save the file, and put it in the same folder as your web page. In your web page, define a script block, but don’t supply any code. Instead, add the src attribute and indicate the script file you want to link to:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<title>A Simple JavaScript Example</title>

<script src="MessageScripts.js"></script>

</head>

<body>

<p>At some point in the processing of this page, a script block

will run and show a message box.</p>

<script>

showMessage()

</script>

<p>If you get here, you've already seen it.</p>

</body>

</html>

When a browser comes across this script block, it requests the MessageScripts.js file and treats it as though the code were right inside the page. That means you can call the showMessage() function in exactly the same way you did before.

NOTE

Even though the script block doesn’t actually contain any code when you use external script files, you must still include the closing </script> tag. If you leave that out, the browser assumes everything that follows—the rest of the page—is part of your JavaScript code.

You can also link to JavaScript functions on another website—just remember that the src attribute in the <script> element needs to point to a full URL (like http://SuperScriptSite.com/MessageScript.js) instead of just a file name. This technique is necessary for plugging into other companies’ web services, like Google Maps (Showing a Map).

Responding to Events

So far, you’ve seen how to run script right away—by weaving a script block into your HTML markup. But it’s far more common to trigger code after the page is finished processing, when the user takes a specific action—like clicking a button or moving the mouse pointer over an element.

To do so, you need to use JavaScript events, which are notifications that an HTML element sends out when specific things happen. For example, JavaScript gives every element an event named onMouseOver (a compressed version of “on mouse over”). As the name suggests, this event takes place (or fires, to use programmer-speak) when a visitor moves his mouse pointer over an HTML element like a paragraph, link, image, table cell, or text box. That action triggers the onMouseOver event and your code flies into action.

This discussion brings up one key question: How do you link your code to the event you want to use? The trick is to add an event attribute to the appropriate element. So if you want to handle the onMouseOver event of an <img> element, you need markup like this:

<img src="sunny.jpg" alt="A sunny day" onmouseover="showMessage()">

NOTE

In JavaScript, function, variable, and object names are case-sensitive, meaning showMessage is not the same as showMESSAGE (and the latter fails). However, the event attribute names are not case sensitive, because they are technically a part of HTML markup, and HTML tolerates any combination of uppercase and lowercase letters. Even so, it’s common to write event attributes with no capitals (as shown here) because this matches the old rules of XHTML, and most programmers are too lazy to reach for the Shift key anyway.

Now, when the mouse moves over the image, and the onMouseOver event fires, the browser automatically calls the showMessage() function. This function pops up a rather unremarkable message box (Figure B-2). When an event triggers a function in this way, that function is called anevent handler.

To use events effectively, you need to know which events JavaScript supports. In addition, you need to know which events work on which HTML elements. Table B-1 provides a list of commonly used events and the HTML elements that they apply to. (You can find a more complete reference at http://developer.mozilla.org/DOM/element.)

In this example, the alert box doesn’t pop up until you move your mouse pointer over the link.

Figure B-2. In this example, the alert box doesn’t pop up until you move your mouse pointer over the link.

Table B-1. Common HTML object events

EVENT NAME

DESCRIPTION

APPLIES TO

onClick

Triggered when you click an element.

Virtually all elements

onMouseOver

Triggered when you move your mouse pointer over an element.

Virtually all elements

onMouseOut

Triggered when you move your mouse pointer away from an element.

Virtually all elements

onKeyDown

Triggered when you press a key.

<select>, <input>, <textarea>, <a>, <button>

onKeyUp

Triggered when you release a pressed key.

<select>, <input>, <textarea>, <a>, <button>

onFocus

Triggered when a control receives focus (in other words, when you position the cursor on the control so you can type something in). Controls include text boxes, checkboxes, and so on—see Revamping a Traditional HTML Form to learn more.

<select>, <input>, <textarea>, <a>, <button>

onBlur

Triggered when focus leaves a control.

<select>, <input>, <textarea>, <a>, <button>

onChange

Triggered when you change a value in an input control. In a text box, this event doesn’t fire until you move to another control.

<select>, <input type=“text”>, <textarea>

onSelect

Triggered when you select a portion of text in an input control.

<input type=“text”>, <textarea>

onError

Triggered when the browser fails to download an image (usually due to an incorrect URL).

<img>

onLoad

Triggered when the browser finishes downloading a new page or finishes loading an object, like an image.

<img>, <body>

onUnload

Triggered when a browser unloads a page. (This typically happens after you enter a new URL or when you click a link. It fires just before the browser downloads the new page.)

<body>

A Few Language Essentials

A brief appendix isn’t enough to cover any language, even one as straightforward as JavaScript. However, the following sections will fill you in on a few language essentials that you’ll need to digest the examples elsewhere in this book.

Variables

Every programming language has the concept of variables—containers that you can use to store bits of information in memory. In JavaScript, every variable is created the same way, by declaring it with the var keyword followed by the variable name. This example creates a variable namedmyMessage:

var myMessage;

NOTE

JavaScript variables are case-sensitive, which means a variable named myMessage differs from one named MyMessage. If you try to use them interchangeably, you’ll wind up with an error message (if your browser is nice) or a bizarre mistake in the page (which is usually what happens).

To store information in a variable, you use the equal sign (=), which copies the data on the right side of the equal sign into the variable on the left. Here’s a one-step example that defines a variable and puts a text value (which is known as a string) inside:

var myMessage = "Everybody loves variables";

You can then use your variable:

// Show the variable text in a message box.

alert(myMessage);

NOTE

JavaScript is a notoriously loose language, and it lets you use variables even if you don’t specifically declare them with the var keyword. However, doing so is considered extremely bad form and is likely to lead to sloppy mistakes.

Null Values

One special value you may run into is null, which is programmer-speak for “nothing.” If a variable is null, it indicates that a given object doesn’t exist or is empty. Depending on the context, this may signal that a specific feature is unavailable. For example, Modernizr (Feature Detection with Modernizr) uses null value tests to determine whether the browser supports certain HTML5 features. You may also check for null values in your scripts—for example, to determine whether you haven’t yet created or stored an object:

if (myObject == null) {

// There is no myObject in existence.

// Now might be a good time to create one.

}

Variable Scope

There are two basic places you can create a variable—inside or outside a function. The following code snippet has one of both:

<script>

var outsideVariable;

function doSomething() {

var insideVariable;

...

}

</script>

If you create a variable inside a function (called a local variable), that variable exists only while that function is running. Here, insideVariable is a local variable. As soon as the doSomething() method ends, the variable is tossed out of memory. That means the next time the page callsdoSomething(), the insideVariable is created from scratch, with none of its previous data.

On the other hand, if you create a variable outside a function (called a global variable), its value lasts as long as the page is loaded in the browser. Furthermore, every function can use that variable. In the previous example, outsideVariable is a global variable.

TIP

The rule of thumb is to use a local variable, unless you specifically need to share your variable with multiple functions, or to retain its value after the function ends. That’s because it’s more trouble to keep track of global variables, and if you use too many, your code becomes messy.

Variable Data Types

In JavaScript, variables can store different data types, such as text, integers, floating point numbers, arrays, and objects. However, no matter what you want to store in your variable, you define it with the same var keyword. You do not set the data type of your variable.

That means you can take the myMessage variable, with its piece of text, and replace that with a numeric value, like this:

myMessage = 27.3;

This behavior makes JavaScript easy to use, because any variable can hold any type of content. It can also let JavaScript mistakes slip past undetected. For example, you might want to grab the text out of a text box and put that in a variable, like this:

var = inputElement.value;

But if you’re not careful, you can accidentally end up putting the entire text box object into the variable, like this:

var = inputElement;

JavaScript allows both actions, so it won’t complain. But a few lines into your code, this mistake will probably lead to some sort of unrecoverable problem. At that point, the browser simply stops running the rest of your code, without giving you any error message to explain what happened. In cases like these, you need the help of a Java-Script debugging tool (see the box on Identifying Errors in JavaScript Code), which can pause your code at any time and let you peer into your variables, so you can see what data they currently contain.

Operations

One of the most useful things you can do with numeric variables is perform operations on them to change your data. For example, you can use arithmetic operators to perform mathematical calculations:

var myNumber = (10 + 5) * 2 / 5;

These calculations follow the standard order of operations (parentheses first, then multiplication and division, then addition and subtraction). The result of this calculation is 6.

You can also use operations to join together multiple pieces of text into one long string. In this case, you use the plus (+) operator:

var firstName = "Sarah";

var lastName = "Smithers";

var fullName = firstName + " " + lastName;

TROUBLESHOOTING MOMENT: IDENTIFYING ERRORS IN JAVASCRIPT CODE

In order to deal with problems (like the variable mistake shown on Variable Data Types), you need to master debugging—the fine art of hunting down the problems in your code and stamping them out. Unfortunately, the way you go about debugging depends on the browser you’re using. Different browsers have different debugging tools (or support different debugging extensions). And while they all serve the same purpose, they don’t work in exactly the same way.

Fortunately, all the information you need is on the Web. Here are some links that can explain how to debug JavaScript mistakes, based on your browser of choice:

§ Internet Explorer. To sort out problems with IE, press F12 to pop up the Developer Tools window. To learn how to use it, visit http://tinyurl.com/debug-ie.

§ Firefox. Serious Firefox developers use a Firefox add-in called Firebug to see what their code is doing at all times. Get it (and learn more) at http://getfirebug.com/javascript.

§ Google Chrome. Chrome has a respectable built-in debugger. To get started, read Google’s debugging tutorial at http://tinyurl.com/c-debugger.

§ Opera. Opera’s debugging tool of choice is Dragonfly. You can learn about it at www.opera.com/dragonfly.

§ Safari. Safari has a powerful set of built-in debugging tools, although tracking down the documentation that explains them can be tricky. You can start with a fairly technical article from the Safari Developer Library at http://tinyurl.com/safari-debug.

Remember, it doesn’t matter what browser and debugging tool you use to correct problems. Once they’re fixed in one browser, they’re fixed for everyone.

Now the fullName variable holds the text “Sarah Smithers.” (The “ ” in the code above tells JavaScript to leave a space between the two names).

When making simple modifications to a variable, there’s a shortcut you’re likely to use. For example, if you have this basic addition operation:

var myNumber = 20;

myNumber = myNumber + 10;

// (Now myNumber is 30.)

You can rewrite it like this:

var myNumber = 20;

myNumber += 10;

// (Now myNumber is 30.)

This trick of moving the operator to the left side of the equal sign works with pretty much any operator. Here are some examples:

var myNumber = 20;

myNumber -= 10;

// (Now myNumber is 10.)

myNumber *= 10;

// (Now myNumber is 100.)

var myText = "Hello";

var myText += " there.";

// (Now myText is "Hello there.")

And if you want to add or subtract the number 1, there’s an even more concise shortcut:

var myNumber = 20;

myNumber++;

// (Now myNumber is 21.)

myNumber--;

// (Now myNumber is 20.)

Conditional Logic

All conditional logic starts with a condition: an expression that is either true or false. Based on the result, you can decide to run some code or to skip over it.

To create a condition, you need to rely on JavaScript’s logical operators, which are detailed in Table B-2.

Table B-2. Logical operators

OPERATOR

DESCRIPTION

==

Equal to.

!=

Not equal to.

===

Exactly equal to (in value and data type).

!==

Not exactly equal to.

!

Not. (This reverses the condition, so if it would ordinarily be true, it is now false, and vice versa.)

<

Less than.

>

Greater than.

<=

Less than or equal to.

>=

Greater than or equal to.

&&

Logical and (evaluates to true only if both expressions are true). If the first expression is false, the second expression is not evaluated.

||

Logical or (evaluates to true if either expression is true). If the first expression is true, the second expression is not evaluated.

Here’s an example of a simple condition:

myNumber < 100

To use this condition to make decisions, you need to put it with an if statement. Here’s an example:

if (myNumber < 100) {

// (This code runs if myNumber is 20, but not if it's 147.)

}

NOTE

Technically, you don’t need the curly brackets around your conditional code, unless you have more than one statement. However, including the brackets is always clearer and avoids potential errors if you do have multiple statements.

When testing equality, make sure you use two equal signs. A single equal sign sets a variable’s value, rather than performing the comparison you want:

// Right:

if (myName == "Joe") {

}

// Wrong:

if (myName = "Sarah") {

}

Although two equal signs are good, it turns out that three may be even better. Many JavaScript pros prefer to test equality using the “exactly equal to” operator (that’s ===) rather than the mere “equal to” operator (==). The difference is that the “equal to” operator will convert data types to try to make a match, while the more stringent “exactly equal to” operator insists on a perfect match of value and data type.

Here’s an example that illustrates the difference:

var myNumberAsText = "45";

// This is true, because the "equal to" operator is willing to convert

// "45" the string to 45 the number.

if (myNumberAsText == 45) {

}

// This is false, because the data types don't match.

if (myNumberAsText === 45) {

}

In most cases, it doesn’t matter whether you use the “equal to” or “exactly equal to” operator, but there are some rare type conversion mistakes that “exactly equal to” can prevent. For that reason, JavaScript experts generally prefer using three equal signs instead of two.

If you want to evaluate more than one condition, one after the other, you can use more than one if block (naturally). But if you want to look at a series of conditions and find the first one that matches (while ignoring the others), you need the else keyword. Here it is at work:

if (myNumber < 100) {

// (This code runs if myNumber is less than 100.)

}

else if (myNumber < 200) {

// (This code runs if myNumber is less than 200 but greater than or equal to

// 100.)

}

else {

// (In all other cases, meaning myNumber is 200 or more, this code runs.)

}

You can include as many or as few conditions as you like in an if block, and adding a final else without a condition is also optional.

Loops

A loop is a basic programming tool that lets you repeat a block of code. The king of JavaScript loops is the for loop. It’s essentially a loop with a built-in counter. Most programming languages have their own version of this construct.

When creating a for loop, you set the starting value, the ending value, and the amount to increment the counter after each pass. Here’s one example:

for (var i = 0; i < 5; i++){

// (This code executes five times.)

alert("This is message: " + i);

}

At the beginning of the for loop is a set of brackets with three important pieces of information. The first portion (in this example, var i = 0) creates the counter variable (i) and sets its initial value (0). The second portion (i < 5) sets a termination condition. If it’s not true (for example, iis increased to 5), the loop ends and the code inside is not repeated again. The third portion (i++), increments the counter variable. In this example, the counter is incremented by 1 after each pass. That means i will be 0 for the first pass, 1 for the second pass, and so on. The end result is that the code runs five times and shows this series of messages:

This is message: 0

This is message: 1

This is message: 2

This is message: 3

This is message: 4

Arrays

The for loop pairs naturally with the array—a programming object that stores a list of values.

JavaScript arrays are remarkably flexible. Unlike in many other programming languages, you don’t define the number of items you want an array to store in JavaScript. Instead, you simply begin by creating an empty array with square brackets, like this:

var colorList = [];

You can then add items using the array’s push() method:

colorList.push("blue");

colorList.push("green");

colorList.push("red");

Or you can place an array item in a specific position. If this memory slot doesn’t already exist, JavaScript creates if for you, happily:

colorList[3] = "magenta";

And you can pull it out yourself, also by position:

var color = colorList[3];

NOTE

Just remember that JavaScript arrays use zero-based counting: The first item in an array is in slot 0, the second is in slot 1, and so on.

Once you have an array stocked with items, you can process each of them using a for loop like this:

for (var i = 0; i < colorList.length; i++) {

alert("Found color: " + colorList[i]);

}

This code moves from the first item (the item at position 0) to the last item (using the array’s length property, which reports its total item count). It shows each item in a message box, although you could surely think of something more practical to do with your array items.

Using a for loop to process an array is a basic technique in JavaScript. You’ll use it often in this book, with arrays that you create yourself and ones that are provided to you by other JavaScript functions.

Functions That Receive and Return Data

Earlier, you saw a simple function, showMessage(). When you called showMessage(), you didn’t need to supply any data, and when it finished, it didn’t provide you with any additional information.

Functions aren’t always that simple. In many cases, you need to send specific information to a function, or take the results of a function and use them in another operation. For example, imagine you want to create a version of the showMessage() function that you can use to show different messages. To do so, you need to make the showMessage() function accept a single parameter. This parameter represents the customized text you want to incorporate into your greeting.

To add the parameter, you must first give it a name, say customMessage, and put it in parentheses after the function name, like so:

function showMessage(customMessage) {

alert(customMessage);

}

NOTE

There’s no limit to how many pieces of information a function can accept. You just need to separate each parameter with a comma.

Inside the function, it can work with the parameters just like normal variables. In this example, the function simply takes the supplied text and shows it in a message box.

Now, when calling the showMessage() function, you need to supply one value (called an argument) for each of the function’s parameters:

showMessage("Nobody likes an argument.");

Parameters let you send information to a function. You can also create functions that send information back to the script code that called them. The key to doing this is the return command, which you put right at the end of your function. The return command ends the function immediately, and spits out whatever information your function generates.

Of course, a sophisticated function can accept and return information. For example, here’s a function that multiplies two numbers (the numberA and numberB parameters) and returns the result to anyone who’s interested:

function multiplyNumbers(numberA, numberB) {

return numberA * numberB;

}

Here’s how you use this function elsewhere on your web page:

// Pass in two numbers, and get the result.

var result = multiplyNumbers(3202, 23405);

// Use the result to create a message.

var message = "The product of 3202 and 23405 is " + result;

// Show the message.

showMessage(message);

Of course you don’t really need a function to multiply numbers (an ordinary JavaScript calculation can do that), nor do you need a function to show a message box (because the built-in alert() function can handle that job). But both examples do a good job of showing you how functions tick, and you’ll use parameters and return values in the same way in more complex functions.

Objects

Virtually all modern programming languages include the concept of an object, which is a package of related data and features that you can interact with in code. For example, every HTML element on a web page is an object in the eyes of your code. Using the different properties of this object, you can read or alter its content, change its style, and handle its events.

Programmers often need to create their own objects, too. For example, you’ll create circle objects in the circle-drawing example in Chapter 9 (Keeping Track of What You’ve Drawn) and ball objects for the bouncing ball example on Animating Multiple Objects.

Objects make complex programming tasks easier, particularly when you need to manage multiple copies of the same data structure. For example, if you need to fill a page with bouncing balls, it would be a serious headache to create dozens and dozens of variables to hold the position and speed of each individual ball. But if you have a way to declare a template for your balls, you can reuse that single template to create as many live ball objects as you need, whether that’s just one or eighty-four thousand.

Most languages have a specific syntax for creating object templates. Often, these templates are called classes. But JavaScript doesn’t include an official class feature. This oversight is due to JavaScript’s history—it started life as a simple, streamlined scripting language, not a serious tool for building online apps. Fortunately, clever JavaScript programmers have found ways to fill the object gaps. Although their tricks began as inventive-but-odd hacks, they’re now considered standard practice.

For example, if you need to define an object in JavaScript, you write an object-definition function for it. This object-definition function is the template that takes the place of a true class in languages like C#, Java, and Visual Basic. Here’s an object-definition function that lets you createPerson objects:

function Person() {

this.firstName = "Joe";

this.lastName = "Grapta";

}

The object-definition function has a single task. It defines, one at a time, all the individual bits of data that constitute that object. In the case of the Person object shown above, this includes two details: a first and last name. (You could easily add additional details, like a date of birth, email address, and so on.) The this keyword is the magic touch—it makes sure that each property you create will become part of the object.

As long as you start the line with this followed by a dot, you can name the property variable whatever you want. So the following example is an equally valid person that stores the same data, but with different property names:

function Person() {

this.F_name = "Joe";

this.L_name = "Grapta";

}

Now you can use the Person() function to create a new person object. The trick is that you don’t want to call the function and trigger its code. Instead, you want to create a new copy of the function by using the new keyword. Here’s how that works:

// Create a new Person, and store it in a variable named joePerson.

var joePerson = new Person();

Once you have a live object, you can access all its details through the property names that you used in the object-definition function:

// Read the firstName property.

alert("His name is " + joePerson.firstName);

// Change the firstName property.

joePerson.FirstName = "Joseph";

You can improve your object-definition function so your code specifies some or all the data details through arguments. This saves you the trouble of creating your object and then customizing it with additional lines of code. It also makes sure your object starts out in the correct state, avoiding potential mistakes. Here’s an example that updates the Person() function in this way:

function Person(fname, lname) {

this.firstName = fname;

this.lastName = lname;

}

And here’s how you use the new Person() function to create two objects:

var newCustomer1 = new Person("Christy", "Shanks");

var newCustomer2 = new Person("Emilio", "Taginelle");

Keeping Track of What You’ve Drawn has a full walkthrough of an example that uses basic object creation, and you’ll see the same technique at work throughout this book.

Object Literals

In the previous section, you saw how to create objects in JavaScript using a function, which acts as a template. When you want to formally define the ingredients that make up an object, using a function is the best approach. It leads to well-organized code and makes complex coding tasks easier. It’s the best choice when you want to work with your objects in different ways and in different places in your code. But sometimes you just need a quick way to create an object for a one-off task. In this case, an object literal makes sense, because it requires nothing more advanced than a pair of curly braces.

To create an object literal, you use an opening curly brace, supply a comma-separated list of properties, and then end with a closing curly brace. You can use spacing and line breaks to make your code more readable, but that’s not required. Here’s an example:

var personObject = {

firstName="Joe",

lastName="Grapta"

};

For each property, you specify the property name and its starting value. Thus, the above code sets personObject.firstName to the text “Joe” and personObject.lastName to “Grapta.”

The example on Setting Geolocation Options uses object literals to send information to the geolocation system. As long as you use the right property names (the ones the getCurrentPosition() method is expecting), an object literal works perfectly.

TIP

If you want to learn more about object literals, object functions, and everything else to do with custom objects in JavaScript, check out the detailed information at www.javascriptkit.com/javatutors/oopjs.shtml.

Interacting with the Page

So far, you’ve seen the right way to put JavaScript in a page, but you haven’t done anything impressive (in fact, you haven’t done anything but pop up a message box). Before going ahead, you need to know a bit more about the role JavaScript typically plays.

First, it’s important to understand that JavaScript code is sandboxed, which means its capabilities are carefully limited. Your page can’t perform any potentially risky tasks on your visitor’s computer, like sending orders to a printer, accessing files, running other programs, reformatting a hard drive, and so on. This design ensures good security, even for careless visitors.

Instead, JavaScript spends most of its time doing one of these tasks:

§ Updating the page. Your script code can change elements, remove them, or add new ones. In fact, JavaScript has complete flexibility to change every detail about the currently displayed HTML, and can even replace the whole document.

§ Retrieving data from the server. JavaScript can make new web requests from the same web server that sent the original page. By combining this technique with the one above, you can create web pages that seamlessly update important information, like a list of news stories or a stock quote.

§ Sending data to the server. HTML already has a way to send data to a web server, called web forms (Chapter 4). But JavaScript can take a much more subtle approach. It can grab bits of information out of your form controls, validate them, and even transmit them to the web server, all without forcing the browser to refresh the page.

The last two techniques require the XMLHttpRequest object, a JavaScript extension that’s described on The XMLHttpRequest Object. In the following sections, you’ll take a look at the first of these, which is a fundamental part of almost every JavaScript-powered page.

Manipulating an Element

In the eyes of JavaScript, your page is much more than a static block of HTML. Instead, each element is a live object that you can examine and modify with JavaScript code.

The easiest way to get hold of an object is to identify it with a unique name, which you apply through the id attribute. Here’s an example:

<h1 id="pageTitle">Welcome to My Page</h1>

Once you give your element a unique ID, you can easily locate that object in your code and have JavaScript act on it.

JavaScript includes a handy trick for locating an object: the document.getElementById() method. Basically, document is an object that represents your whole HTML document. It’s always available, and you can use it anytime you want. This document object, like any object worthy of the name, gives you some handy properties and methods. The getElementById() method is one of the coolest—it scans a page looking for a specific HTML element.

NOTE

If you’re familiar with the basics of object-oriented programming, properties and methods are old hat. If not, you can think of properties as data attached to an object, and you can think of methods as functions built into an object.

When you call the document.getElementById() method, you supply the ID of the HTML element you’re looking for. Here’s an example that digs up the object for an HTML element with the ID pageTitle:

var titleObject = document.getElementById("pageTitle");

This code gets the object for the <h1> element shown earlier and stores it in a variable named titleObject. By storing the object in a variable, you can perform a series of operations on it without having to look it up more than once.

So what, exactly, can you do with HTML objects? To a certain extent, the answer depends on the type of element you’re working with. For example, if you have a hyperlink, you can change its URL. If you have an image, you can change its source. And there are some actions you can take with almost all HTML elements, like changing their style or modifying the text that appears between the beginning and ending tags. As you’ll see, you’ll find these tricks useful in making your pages more dynamic—for example, you can change a page when a visitor takes an action, like clicking a link. Interactions like these make visitors feel as though they’re using an intelligent, responsive program instead of a plain, inert web page.

Here’s how you modify the text inside the just-mentioned <h1> element, for example:

titleObject.innerHTML = "This Page Is Dynamic";

This script works because it uses the property named innerHTML, which sets the content that’s nested inside an element (in this case, an <h1> element with the page title). Like all properties, innerHTML is just one aspect of an HTML object you can alter. To write code statements like this, you need to know what properties JavaScript lets you play with.

Obviously, some properties apply to specific HTML elements only, like the src attribute that’s used to load a new picture into this <img> element:

var imgObject = document.getElementById("dayImage");

dayImage.src = "cloudy.jpg";

You can also tweak CSS properties through the style object:

titleObject.style.color = "rgb(0,191,255)";

Modern browsers boast a huge catalog of DOM properties you can use with just about any HTML element. Table B-3 lists some of the most useful.

Table B-3. Common HTML object properties

PROPERTY

DESCRIPTION

className

Lets you retrieve or set the class attribute (see Formatting the Right Elements with Classes). In other words, this property determines what style (if any) this element uses. Of course, you need to define this style in an embedded or linked style sheet, or you’ll end up with the plain-Jane default formatting.

innerHTML

Lets you read or change the HTML inside an element. The innerHTML property is insanely useful, but it has two quirks. First, you can use it on all HTML content, including text and tags. So if you want to put bold text inside a paragraph, you can set innerHTML to <b>Hi</b>. Second, when you set innerHTML, you replace all the content inside this element, including any other HTML elements. So if you set the innerHTML of a <div> element that contains several paragraphs and images, all of these items disappear, to be replaced by your new content.

parentElement

Provides the HTML object for the element that contains this element. For example, if the current element is a <b> element in a paragraph, this gets the object for the <p> element. Once you have this element, you can modify it too.

style

Bundles together all the CSS attributes that determine the appearance of the HTML element. Technically, the style property returns a full-fledged style object, and you need to add another dot (.) and the name of the style attribute you want to change, as in myElement.style.fontSize. You can use the style object to dictate colors, borders, fonts, and even positioning.

tagName

Provides the name of the HTML element for this object, without the angle brackets. For example, if the current object represents an <img> element, this returns the text “img.”

TIP

HTML elements also provide a smaller set of useful methods, including some for modifying attributes, like getAttribute() and setAttribute(); and some for adding or removing elements, like insertChild(), appendChild(), and removeChild(). To learn more about the properties and methods that a specific HTML element supports, check out the reference athttp://developer.mozilla.org/DOM/element.

Connecting to an Event Dynamically

On Responding to Events, you saw how to wire up a function using an event attribute. However, it’s also possible to connect an event to a function using JavaScript code.

Most of the time, you’ll probably stick to event attributes. However, there are cases where that isn’t possible or convenient. One of the most common examples is when you create an HTML object in your code and then add it to the page dynamically. In this situation, there’s no markup for the new element, so there’s no way to use an event attribute. (You’ll see this technique in the canvas-drawing example in Chapter 8.) Another case is when you’re attaching an event to a built-in object rather than an element. (You’ll see this example when you handle storage events in Chapter 10.) For all these reasons, it’s important to understand how to wire up events with code.

NOTE

There are several different ways to attach events, but they aren’t all supported by all browsers. This section uses the event property approach, which is supported by all. Incidentally, if you decide to use a JavaScript toolkit like jQuery, you’ll probably find that it adds yet another event-attaching system, which will work on all browsers and may provide a few extra features.

Fortunately, attaching events is easy. You simply set an event property that has the same name as the event attribute you would normally use. For example, say you have an <img> element like this somewhere on your page:

<img id="dayImage" src="sunny.jpg" alt="The weather">

Here’s how you tell the browser to call the swapImage() method when that image is clicked:

var imgObject = document.getElementById("dayImage");

imgObject.onclick = swapImage;

However, don’t make this mistake:

imgObject.onclick = swapImage();

This runs the swapImage() function, takes the result (if it returns one), and uses that to set the event handler. This is almost certainly not what you want.

To understand what really happens when the <img> element is clicked, you need to look at the code in the swapImage() function. It grabs the <img> element and modifies the src attribute to point to a new picture (see Figure B-3):

// Keep track of whether the picture has been swapped from day to night.

var dayTime = true;

// This function runs when the onClick event happens.

function swapImage() {

var imgObject = document.getElementById("dayImage");

// Flip from day to night or night to day, and update the picture to match.

if (dayTime === true) {

dayTime = false;

imgObject.src = "cloudy.jpg";

}

else {

dayTime = true;

imgObject.src = "sunny.jpg";

}

}

Click this picture, and the page fires an event. That event triggers a function, and that function loads a new image.

Figure B-3. Click this picture, and the page fires an event. That event triggers a function, and that function loads a new image.

Sometimes, an event passes valuable information to your event-handling function. To capture this information, you need to add a single parameter to your function. By convention, this parameter is usually named event or just e:

function swapImage(e) {

...

}

The properties of the event object depend on the event. For example, the onMouseMove event supplies the current mouse coordinates (which you’ll use when creating the painting program on Building a Basic Paint Program).

There’s one more fine point to note. When you use code to connect an event, you must put the entire event name in lowercase letters. This is different from when you wire up an event using an attribute in HTML. Unlike JavaScript, HTML doesn’t care one whit about case.

NOTE

This book refers to events using an easy-to-read convention called Pascal case, which uses uppercase letters to indicate each new word (for example, onLoad and onMouseOver). However, the code listings use all lowercase letters (for example, onload and onmouseover) because JavaScript requires it.

Inline Events

In order for the previous example to work, the swapImage() function must be defined somewhere else in your code. Sometimes, you may want to skip this step and define the function code in the same place where you attach the function to the event. This slick technique is called an inline function.

Here’s an example that connects an inline function to the onClick event:

var imgObject = document.getElementById("dayImage");

imgObject.onclick = function() {

// The code that went in the swapImage() function

// now goes here.

if (dayTime === true) {

dayTime = false;

imgObject.src = "cloudy.jpg";

}

else {

dayTime = true;

imgObject.src = "sunny.jpg";

}

};

This shortcut approach to event handling is less common than using a separate, named function to handle the event. However, it’s still a useful convenience, and the examples in this book use it occasionally.

NOTE

Inline functions are sometimes useful when you’re dealing with an asynchronous task—a task that the browser handles in the background. When an asynchronous task is finished, the browser fires an event to notify your code. Sometimes, the clearest way to deal with this situation is to put the code that handles the completion of a task right next to the code that triggered the startof the task. (Drawing Images shows an example with a picture that’s loaded asynchronously and then processed.)

Finally, there’s one sort of inline function that’s used in many of the examples in this book. It’s the event handler for the window’s onLoad event, which fires after the entire page is rendered, displayed, and ready to go. This makes it a logical point for your code to take over. If you try to run code before this point, you might run into trouble if an object hasn’t been created yet for the element you want to use:

<script>

window.onload = function() {

alert("The page has just finished loading.);

}

</script>

This approach frees you from worrying about the position of your script block. It lets you place the initialization code in the <head> section, where it belongs, with the rest of your JavaScript functions.