Chapter 1. Hello JavaScript!

One reason JavaScript is so popular is that it’s relatively easy to add JavaScript to a web page. All you need to do, at a minimum, is include an HTML script element in the page, specify "text/javascript" for the type attribute, and add whatever JavaScript you want:

<script type="text/javascript">
...some JavaScript
</script>

Installation is not required, nor do you have to torturously work through any odd library path configurations. JavaScript works, straight out of the box and in most web browsers, including the big four: Firefox, Internet Explorer, Opera, and Safari. All you need to do is add a scripting block, and you’re in business.

Traditionally, you add JavaScript blocks to the head element in the document (delimited by opening and closing head tags), but you also can include them in the body element—or even in both sections. However, adding script to the body is not usually considered a good technique, as it makes it more difficult to find the script when you’re modifying it at a later time. The exception to this rule is when performance is an issue, which I’ll cover in Chapter 6. All of the examples in this book add scripting blocks only to the web page head section.

Hello World!

Also traditionally, the first example when learning a new programming language is known as “Hello, World”—a simple application that prints out “Hello, World!” to the user interface, whatever it may be. In the case of JavaScript, the user interface is the web page. Example 1-1 shows a web page with a JavaScript block that, using only one line of JavaScript, pops open a small window commonly called an alert box with the words “Hello, World!”

Example 1-1. The smallest JavaScript application: “Hello, World!”

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Hello, World!</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript">

alert("Hello, World!");

</script>
</head>
<body>
</body>
</html>

Copying Example 1-1 into a file and opening the file in web browsers that support JavaScript should result in an alert box that reads “Hello, World!” If it doesn’t, you might want to make sure you have JavaScript enabled.

Note

Older versions of Internet Explorer also disable script if you open the page via the File Open menu rather than by using a web page address such as http://<somedomain.com>/index.html.

This application, although very limited in functionality, more or less demonstrates the minimum components of a JavaScript application: you have a web page, you have a script element, and you have a line of JavaScript. Try it yourself, except edit the string by replacing “World” with your first name.

Of course, if you want to move beyond just outputting a static message to the browser, you’ll need to extend the example somewhat.

Hello World! Once Again

Another variation of the “Hello, World!” application actually writes the message to the web page rather than in an alert box. To do so, it makes use of four important JavaScript application components: the built-in browser document object, JavaScript variables, a JavaScript function, and an event handler. As impressive as this may sound, you can still code the application in seven lines of JavaScript, as shown in Example 1-2.

Example 1-2. “Hello, World!” printed out to the web page

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Hello, World!</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript">
function hello() {

   // say hello to the world
   var msg = "Hello, World!";
   document.open();
   document.write(msg);
   document.close();
}
</script>
</head>
<body onload="hello()">
<p>Hi</p>
</body>
</html>

Though Example 1-2 is a very small application, it does expose several of the basic components of most JavaScript applications in use today, each of which deserves a closer look. In the rest of this chapter, we’ll take that closer look, one component at a time.

Note

Not covered in this chapter is the Document Type Declaration (DOCTYPE) used in Examples 1-1 and 1-2, which can have an influence on how different browsers process the JavaScript. I’ll cover the impact of a DOCTYPE in Chapter 6.

The script Tag

JavaScript is frequently used within the context of another language, such as markup languages like HTML and XHTML. However, you can’t just plop JavaScript into the markup wherever and however you want.

In Example 1-2, the script element encloses the JavaScript. This lets the browser know that when it encounters the script element’s opening tag, it shouldn’t process the element’s contents as HTML or XHTML. At this point, control over the content is turned over to the browser’s scripting engine.

Not all script embedded in web pages is JavaScript, and the script element opening tag contains an attribute defining the type of script. In the example, this is given as text/javascript. Among other allowable values for the type attribute are:

  • text/ecmascript

  • text/jscript

  • text/vbscript

  • text/vbs

The first type value listed specifies that the script is interpreted as ECMAScript, based on the ECMA-262 scripting standard. The next value causes the script to be interpreted as JScript, a variation of ECMAScript that Microsoft implements in Internet Explorer. The last two values are for Microsoft’s VBScript, a completely different scripting language.

All of these type values describe the MIME type of the content. MIME, or Multipurpose Internet Mail Extension, is a way to identify how the content is encoded (i.e., text), and its specific format (javascript). By providing a MIME type, those browsers capable of processing the type do so, whereas other browsers skip over the section. This ensures that only applications that can process the script actually access the script.

Earlier versions of the script tag took a language attribute, which was used to designate the version of the language, as well as the type: javascript1.2 as compared to javascript1.1. However, the use of language was deprecated in HTML 4.01, though it still appears in many JavaScript examples. And therein lies one of the earliest cross-browser techniques.

Note

I use the term cross-browser to denote JavaScript that works across all target browsers, or uses functionality to manage any browser differences so that the application works “cross-browser.”

Years ago, when working with cross-browser compatibility issues, it wasn’t uncommon to create a specific script for each browser in a separate section or file and then use the language attribute to ensure that only a compatible browser could access the code. Looking through some of my old examples (circa 1997), I found the following:

<script src="ns4_obj.js" language="javascript1.2">
</script>
<script src="ie4_obj.js" language="jscript">
</script>

The philosophy of this approach was that only a browser capable of processing JavaScript 1.2 would pick up the first file (primarily Netscape Navigator 4.x at that time) and only a browser capable of processing JScript would pick up the second file (Internet Explorer 4). Kludgey? Sure, but it also worked through the early years of trying to deal with frequently broken cross-browser dynamic page effects.

Other valid script attributes are src, defer, and charset. The charset attribute defines the character encoding used with the script. It usually isn’t set unless you need a different character encoding than what’s defined for the document.

One attribute that can be quite useful is defer. If you set defer to a value of "defer", it indicates to the browser that the script is not going to generate any document content, and the browser can continue processing the rest of the page’s content, returning to the script when the page has been processed and displayed:

<script type="text/javascript" defer="defer">
...no content being generated
</script>

The defer attribute can help speed up page loading when you have a larger JavaScript block or include a larger JavaScript library.

The last attribute, src, has to do with loading external JavaScript files, which we’ll explore a little later. First, though, we’ll take a closer look at the text/javascript type attribute, and what this means for each browser.

JavaScript Versus ECMAScript Versus JScript

Example 1-2 used the text/javascript type with the script element, and the application works with Firefox, IE, Opera, and Safari. However, not all browsers implement JavaScript.

Although the name “JavaScript” has become ubiquitous for client-side browser-based scripting, only Mozilla and the popular Mozilla browser, Firefox, implement JavaScript, which is the actual name of an instance of a broader-based scripting specification, ECMAScript. ECMAScript is actually the industry-wide client-side scripting specification. The latest released version of ECMAScript is ECMA-262, Edition 3.

However, most browsers honor the text/javascript type, in addition to the more appropriate (though far less common) text/ecmascript, though there can be differences, even significant differences, in exactly what each browser or other application supports.

Note

ECMAScript isn’t restricted to just browsers: Adobe’s ActionScript support in Flash is based on ECMA-262, Edition 3.

All of the browsers used to test the applications in the book—Firefox 3.x, Safari 3.x, Opera 9.x, and IE8—support most, if not all, of ECMA-262, Edition 3, and even some of the next generation of ECMAScript, ECMAScript 3.1 (and beyond). In this book, I’ll note whenever there are browser differences or provide cross-browser workarounds. I’ll also be using the more familiar text/javascript for the script element’s type attribute, as shown in Example 1-2.

Defining Functions in JavaScript

In Example 1-2, the part of the JavaScript that actually creates the “Hello, World!” message exists within a function named hello. Functions are ways of enclosing one or more lines of script so that they can be executed one or more times. You also use functions to control when the enclosed script is executed. For instance, in Example 1-2, the function is called only after the web page is loaded.

Here is the typical syntax for creating a function:

function functionname(params) {
    ...
}

The keyword function is followed by the function name and parentheses containing zero or more parameters (function arguments). In Example 1-2, there are no parameters, but we’ll see plenty of examples with parameters throughout the book. The script that makes up the function is then enclosed in curly braces.

I say “typical” when providing the function syntax because this isn’t the only syntax that you can use to create a function. However, we’ll get into other variations starting in Chapter 5, which covers JavaScript functions in detail.

Of course, once you have a function, you have to invoke it to run the script it contains, which leads us to event handlers.

Event Handlers

In the opening body tag of Example 1-2, an HTML attribute named onload is assigned the hello function. The onload attribute is what’s known as an event handler. This event handler, and others, is part of the underlying object model that each browser provides.

You use event handlers to map a function to a specific event so that when the event occurs, the function’s script is processed. One of the more commonly used event handlers is the one just demonstrated, the onload event attached to the body element. When the web page has finished loading, the event is fired, and the handler calls the mapped function.

Here are some commonly used event handlers:

onclick

Fired when the element receives a mouse click

onmouseover

Fired when the mouse cursor is over the element

onmouseout

Fired when the mouse cursor is no longer over the element

onfocus

Fired when the element gains focus (through the mouse or keyboard)

onblur

Fired when the element no longer has focus

These are only a few of the event handlers, and not all elements support all event handlers. The onload event handler is supported for only a few elements, such as the body and img elements—not surprising, as the event is associated with loading something.

Adding an event handler directly to the opening element tag is one way to attach an event handler. A second technique occurs directly within JavaScript using syntax such as the following:

<script type="text/javascript">
window.onload=hello;

function hello(??) {

   // say hello to the world
   var msg = "Hello, World!";
   document.open();
   document.writeln(msg);
   document.close();
}
</script>

The onload event handler is a property of another built-in browser object, the window. The first line of the script then assigns the function, hello, directly to the window’s onload event handler.

Note

JavaScript functions are also objects in JavaScript, so you can assign a function, by name or directly, to a variable or another object’s property.

Using the object property approach, you don’t have to add event handlers as attributes into element tags, but instead can add them into the JavaScript itself. We’ll get into more details on event handlers and more advanced forms of event handling beginning in Chapter 7. In the meantime, let’s take a closer look at the document object.

The document Browser Object

Example 1-2, as small as it is, used one of the most powerful objects available in your browser: the document object. The document object is, for all intents and purposes, a representation of the page, including all of the elements within it. It’s through the document that we can access the page contents, and as you’ve just seen, it’s through the document that we can also modify the page contents.

The document has collections mapped to page elements, such as all the images or form elements in the page. It also has methods that you can use to both access and alter the web page, including the open, writeln, and close methods used in Example 1-2.

The open method opens the document for writing. In Example 1-2, the document opened was the same document with which the script is contained. The writeln method is a variation of the write method, which outputs a string of text to the document. The only difference between write and writeln is that writeln also appends a newline character following the text. The close method closes the document, and also forces the immediate rendering of the document contents.

An unfortunate consequence of writing to the existing document after the page is loaded is that the existing contents of the document are erased. That’s why when you open the page you’ll see the “Hello, World!” message but you won’t see the “Hi” that’s already in the page.

Warning

Another consequence of writing over the existing document is that with IE, at least with the beta of IE8, you’ll lose your back button functionality.

The open and close methods aren’t required for Example 1-2, as browsers will automatically open and close the document when the writeln method is called after the document is already loaded. If you used the script in the body of the page, you would need to explicitly call the open method.

The document, as well as the window mentioned earlier, is part of a hierarchy of objects known as the Browser Object Model (BOM). The BOM is a basic set of objects implemented in most modern browsers. I cover the document and other BOM objects in Chapter 9.

Note

The BOM is the earliest version of the more formal Document Object Model (DOM), and is sometimes referred to as DOM Level 0.

The property Operator

In Example 1-2, you accessed the methods from the document object through one of the many operators supported in JavaScript: the property operator, represented by a single dot (.).

Several operators are available in JavaScript: those for arithmetic (+, –), those for conditional expressions (<, >), and others that I detail more fully later in the book. One of the most important, though, is the property operator. Data elements, event handlers, and object methods are all considered properties of objects within JavaScript, and you access all of them via the property operator.

You also use the property operator in a process called method chaining, or sometimes just chaining, whereby you can apply calls to multiple methods, one after another, all within the same statement. We’ll see the following example in the book:

var tstValue = document.getElementById("test").style.backgroundColor="#ffffff";

In this example, a page element is accessed using the document method getElementById, and its style object is accessed to set the background color for that element. The backgroundColor is a property of the style object, which is a property of the page element, which is accessed through the method getElementById, which is a property of the document object.

I cover all of these methods and objects in future chapters, but I wanted to introduce you to method chaining now, as you’ll see it frequently. You cannot chain all properties of all objects—only those that return an object.

Note

One of the more popular Ajax libraries, JQuery, makes extensive use of method chaining. I’ll cover JQuery briefly in Chapter 14.

The var Keyword and Scope

The “Hello, World!” string I used in Example 1-2 is assigned to an object named msg, which is an example of a JavaScript variable. A variable is nothing more than a named reference to a piece of data. The data can be a string, as in Example 1-2, a number, or the boolean value of true or false. It can also be a function reference, an array, or another object.

In the example, I defined the variable with the var keyword. When you use var with a variable, you’re defining the variable with local scope, which means you can access them only within the function in which you’ve defined them. If I didn’t use var, the variable msg would be global and would have scope inside and outside the function. Using a global variable in a local context isn’t a bad thing—and it may be necessary at times—but it isn’t a good practice, and you should avoid it if possible.

The reason why you want to avoid global variables is because if the application is part of a larger JavaScript application, msg may be in use in another part of the code in another file, and you will have overridden whatever data it originally contained. Or, if you create a global variable called msg, some other library’s script could override it by not correctly using the var keyword, and the data you were tracking will be lost.

Setting the scope of a variable is important if you have global and local variables with the same name. Example 1-2 doesn’t have global variables of any name, but it’s important to develop good JavaScript coding practices from the beginning.

Here are the rules regarding scope:

  • If you declare a variable with the var keyword in a function or block of code, its use is local to that function.

  • If you use a variable without declaring it with the var keyword, and a global variable of the same name exists, the local variable is assumed to be the already existing global variable.

  • If you declare a variable locally with a var keyword, but you do not initialize it (i.e., assign it a value), it is local and accessible but not defined.

  • If you declare a variable locally without the var keyword, or explicitly declare it globally but do not initialize it, it is accessible globally, but again, it is not defined.

By using var within a function, you can prevent problems when using global and local variables of the same name. This is especially critical when using JavaScript libraries—such as Dojo, jQuery, and Prototype—because you’re not going to know what variable names the other JavaScript code is using.

Statements

JavaScript also supports different types of processing instruction types, known as statements. Example 1-2 demonstrated a basic type of JavaScript statement: the assignment, whereby a value is assigned to a variable. Other types of statements are for loops, which process a script block a given number of iterations; the if…else conditional statement, which checks a condition to see whether the script block is executed; the switch statement, which checks for a value in a given set and then executes the script block associated with that value; and so on.

Each type of statement has certain syntax requirements. In Example 1-2, the assignment statement ended with a semicolon. Using a semicolon to terminate a statement isn’t a requirement in JavaScript unless you want to type many statements on the same line. If you do, you’ll have to insert a semicolon to separate the individual statements.

When you type a complete statement on one line, you use a line break to terminate the statement. However, just as with the use of var, it’s good practice to use semicolons to terminate all statements, if for no other reason than it makes the code easier to read. More on the semicolon, other operators, and statements in Chapter 3.

Comments

As this chapter hopefully demonstrates, there’s quite a lot to the JavaScript in even a small application such as Example 1-2. Hold on, though, as we’re not quite finished. Last, but certainly not least, a word on JavaScript comments.

Comments provide a summary or explanation of the code that follows. Comments in JavaScript are an extremely useful way of quickly noting what a block of code is doing and whatever dependencies it has. It makes the code more readable and more maintainable.

You can use two different types of comments in your own applications. The first, using the double slash (//), comments out whatever follows in the line:

// This line is commented out in the code
var i = 1; // this is a comment in the line

The second makes use of opening and closing JavaScript comment delimiters, /* and */, to mark a block of comments that can extend one or more lines:

/* This is a multiline comment 
that extends through three lines. 
Multiline comments are particularly useful for commenting on a function */

Single-line comments are relatively safe to use, but multiline comments can generate problems if the beginning or ending bracket character is accidentally deleted.

Typically, you use single-line comments before a block of script performing a specific process or creating a specific object; you use multiline comment blocks in the beginning of a JavaScript file. A good practice to get into with JavaScript is to begin every JavaScript block, function, or object definition with at least one line of comments. In addition, provide a more detailed comment block at the beginning of all JavaScript library files; include information about author, date, and dependencies, as well as a detailed purpose of the script.

We’ve explored what you saw in Example 1-2. Now let’s take a look at what you didn’t see.

What You Didn’t See: HTML Comments and CDATA Sections

Ten years ago, when most browsers were in their first or second version, JavaScript support was sketchy, with each browser implementing a different version. When browsers, such as the text-based Lynx, encountered the script tag, they usually just printed the output to the page.

To prevent this, the script contents were enclosed in HTML comments: <!-- and -->. When HTML comments were used, non-JavaScript-enabled browsers ignored the commented-out script, but newer browsers knew to execute the script.

It was a kludge, but it was a very widespread kludge. Most web pages with JavaScript nowadays feature the added HTML comments because the script is copied more often than not. Unfortunately, some new browsers today may process the web page as XHTML, and as strictly XML, which means the commented code is discarded. In these situations, the JavaScript is ignored. As a consequence, using HTML comments to “hide” the script is actively discouraged.

Another way to “hide” the script, however, is encouraged, and that’s the use of the XML CDATA section, particularly if the script is going to be used in XHTML. Example 1-3 is a modification of Example 1-2 with the addition of a CDATA section, shown in bold.

Example 1-3. Modification of Example 1-2 to add a CDATA section to “hide” the script

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Hello, World!</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript">
//<![CDATA[

function hello() {
   // say hello to the world
   var msg = "Hello, <em>World!</em>";
   document.open();
   document.write(msg);
   document.close();
}

//]]>
</script>
</head>
<body onload="hello()">
<p>Hi</p>
</body>
</html>

The reason for the CDATA section is that XHTML processors interpret markup, such as the em element opening and closing tags in this new example, even when they’re contained within JavaScript strings. Though the script may process correctly and may display the page correctly, if you try to validate it without the CDATA section, you’ll get validation errors, as shown in Figure 1-1.

Validation error without using a CDATA section

Figure 1-1. Validation error without using a CDATA section

JavaScript that is imported into the page using the script element’s src attribute is assumed to be compatible with XHTML and doesn’t require the CDATA section. You should delimit inline or embedded JavaScript with CDATA though, particularly if it’s included within the body element. For most browsers, you’ll also need to hide the CDATA section opening and closing tags with JavaScript comments (//), as shown previously in Example 1-3, or you’ll get a JavaScript error.

Of course, the best way to keep your web pages uncluttered is to remove the JavaScript from the page entirely, through the use of JavaScript files.

Most of this book’s examples are embedded into the page primarily to make them easier to read and follow. However, the Mozilla Foundation recommends (and I agree) that all inline or embedded JavaScript be removed from a page and placed in separate JavaScript files. Using a separate file, covered in the next section, prevents problems with validation and incorrect interpretation of text, regardless of whether the page is processed as HTML or XHTML.

Note

JavaScript files are also more efficient, as the browser caches them the first time they’re loaded. Additional references to the same file are pulled from the cache.

JavaScript Files

JavaScript usage is becoming more object-oriented and complex. To simplify their work, as well as share it, JavaScript developers are creating reusable JavaScript objects that they can incorporate into many applications, including those created by other developers. The only efficient way to share these objects is to create them in separate files and provide a link to each file in the web page. With the code now in files, all the developer needs to do is link the code into the web pages. If the code needs to change later, it’s changed in only one place.

Nowadays, all but the simplest JavaScript is created in separate script files. Whatever overhead is incurred by using multiple files is more than offset by the benefits. To include a JavaScript library or script file in your web page, use this syntax:

<script type="text/javascript" src="somejavascript.js"></script>

The script element contains no content, but the closing tag is still required.

The browser loads script files into the page in the order in which they occur in the page and processes them in order unless defer is used. A script file should be treated as though the code is actually included in the page; the behavior is no different between script files and embedded JavaScript blocks.

Example 1-4 is yet another modification of our “Hello, World!” application, except this time the script is moved to a separate file, named helloworld.js. The .js file extension is required, unless you direct the web server to use some other extension to represent the JavaScript MIME type. However, because the .js has been used as the default for years, it’s best not to get creative.

Note

Every rule always has exceptions, and the use of .js is one of them. If the JavaScript is being dynamically generated using a server-side application built in a language such as PHP, the file will have a different extension.

Example 1-4 contains the script, and Example 1-5 shows the now altered web page.

Example 1-4. The Hello World script, in a separate file

/* 
   function: hello
   author: Shelley
   hello prints out the message, "Hello, World!"
*/

function hello() {

   // say hello to the world
   var msg = "Hello, <em>World!</em>";
   document.open();
   document.write(msg);
   document.close();
}

Example 1-5. The web page, now calling an external script file

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Hello, World!</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript" src="helloworld.js">
</script>
</head>
<body onload="hello()">
<p>Hi</p>
</body>
</html>

As you can see, the page is much cleaner, and the application is more efficient from a maintenance perspective. Also, other applications can now reuse the code. Though it’s unlikely that you’d reuse something as simple as the “Hello, World!” script, you’ll be creating examples later in the book in which reuse becomes more important.

We have one last section of material to cover in this chapter before moving on to variables and data types in Chapter 2.

Accessibility and JavaScript Best Practices

In an ideal world, everyone who visits your website would use the same type of operating system and browser and would have JavaScript enabled. Your site would never be accessed via a mobile phone or some other oddly sized device, vision-impaired people wouldn’t need screen readers, and the paralyzed wouldn’t need voice-enabled navigation.

This isn’t an ideal world, but too many JavaScript developers code as though it is. We get so caught up in the wonders of what we can create that we forget that not everyone can share them.

Many best practices are associated with JavaScript, but if there’s one to take away from this book, it’s the following: whatever JavaScript functionality you create, it must not come between your site and your site’s visitors.

What do I mean by “come between your site and your site’s visitors”? I mean that you should avoid using JavaScript in such a way that those who cannot, or will not, enable JavaScript are prevented from accessing essential site resources. If you create a drop-down menu using JavaScript, you also need to provide a script-free alternative. If your visitors are vision-impaired, JavaScript must not interfere with audio browsers, which happens when instructions are added to a page dynamically.

Many developers don’t follow these practices because they assume the practices require extra work, and for the most part, they do. However, the work doesn’t have to be a burden—not when the results can increase the accessibility of your site. In addition, many companies now require that their websites meet a certain level of accessibility. It’s better to get into the habit of creating accessible pages in the beginning than to try to fix the pages, or your habits, later.

Accessibility Guidelines

The WebAIM site (http://www.webaim.org) has a wonderful tutorial on creating accessible JavaScript (available at http://www.webaim.org/techniques/javascript/). It covers the ways you shouldn’t use JavaScript, such as using JavaScript for menus and other navigation. However, the site also provides ways you can use JavaScript to make a site more accessible.

One suggestion is to base feedback on events that can be triggered whether you use a mouse or not. For instance, rather than capture mouse clicks, you should capture events that are triggered if you use a keyboard or a mouse, such as onfocus and onblur. If you have a drop-down menu, add a link to a separate page, and then provide a static menu on the second page.

After reviewing the tutorial at WebAIM, you might want to spend some time at the World Wide Web Consortium’s (W3C’s) Web Accessibility Initiative (at http://www.w3.org/WAI/). From there, you can also access the U.S. government’s Section 508 website (http://www.section508.gov/), which discusses what is known as “508 compliance.” Sites that comply with Section 508 are accessible regardless of physical constraints. At that website, you can access various tools that evaluate your site for accessibility, such as Cynthia Says (at http://www.cynthiasays.com/).

Whether your site is located within the United States or elsewhere, you want it to be accessible; therefore, a visit to Section 508 is useful regardless of your locale.

Of course, not all accessibility issues are related to those browsers in which JavaScript is limited or disabled by default, such as with screen readers. Many people don’t trust JavaScript, or don’t care for it and choose to disable it. For both groups of people—those who prefer not to use JavaScript, and those who have no choice—it’s important to provide alternatives when no script is present. One alternative is noscript.

noscript

Some browsers or other applications are not equipped to process JavaScript, or are limited in how they interpret the script. If the JavaScript is not essential to navigation or interaction, and the browser ignores the script, no harm. However, if the JavaScript is essential to access the site’s resources and you don’t provide alternatives, you’re basically telling these folks to go away.

Years ago, when JavaScript was fairly new, one popular approach was to provide a plain or text-only page accessible through a link, usually placed at the top of the page. However, the amount of work to maintain the two sites could be prohibitive, and developers had to constantly worry about keeping the sites synchronized.

A better technique is to provide static alternatives to dynamic, script-generated content. When you use JavaScript to create a drop-down menu, also provide a standard hierarchical linked menu; when you use script to expose form elements for editing based on user interaction, provide the more traditional links to a second page to do the same.

The element that enables all of this is noscript. Wherever you need static content, add a noscript element with the content contained within the opening and closing tags. Then, if a browser or other application can’t process the script (because JavaScript is not enabled for some reason), the noscript content is processed; otherwise, it’s ignored.

Example 1-6 is one last variation of “Hello, World!” showing the CDATA-protected example modified with the addition of noscript. Accessing the page with a JavaScript-enabled browser should display a page with “Hello, World!” printed out. However, if you access the page with a script-disabled browser, a different message results.

Example 1-6. The use of noscript for non-JavaScript-enabled browsers

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Hello, World!</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript">
//<![CDATA[

function hello() {
   // say hello to the world
   var msg = "Hello, <em>World!</em>";
   document.open();
   document.write(msg);
   document.close();
}

//]]>
</script>
</head>
<body onload="hello()">
<noscript>
  <p>I'm still here, World!</p>
</noscript>
</body>
</html>

Of course, Example 1-6 is just a simplified use of noscript; you’ll see more sophisticated uses later in the book, as well as alternative script-safe methods.

To test Example 1-6, I used a Firefox extension called the Web Developer Toolbar. On this bar is an option to disable JavaScript support. When JavaScript is active, the original “Hello, World!” message displays. However, when I use the tool to deactivate JavaScript support, another message displays: I'm still here, World! Though you can turn scripting off directly in the browser, I’ve found that development tools such as the Web Developer Toolbar make testing a whole lot easier.

Which tools you use depends on the browser with which you prefer to develop. I prefer developing with Firefox, and make extensive use of the Web Developer Toolbar and Firebug, a sophisticated debugging tool. Later, in Chapter 6, which covers troubleshooting and debugging, we’ll take a closer look at these, as well as tools and options available for other browsers.

Get Learning JavaScript, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.