Section 12.3. JavaScript

All the executable content elements we've discussed so far have had one common trait: they are separate from the browser and the HTML/XHTML document ? separate data, separate execution engine.

JavaScript is different. It is a scripting language that taps the native functionality of the browser. You may sprinkle JavaScript statements throughout your documents, either as blocks of code or single statements attached to individual tags. The JavaScript-enabled browsers, including both Netscape and Internet Explorer, interpret and act upon the JavaScript statements you provide to do such things as alter the appearance of the document, control the display, validate and manipulate form elements, and perform general computational tasks.

As with Java, we do not pretend to teach JavaScript programming in this book. We'll show you how to embed and execute JavaScript within your documents, but we ask that you turn to books like JavaScript: The Definitive Guide (O'Reilly) for a complete reference.

12.3.1 The <script> Tag

One way to place JavaScript code in your document is via the HTML and XHTML standard <script> tag.

Everything between <script> and </script> is processed by the browser as executable JavaScript statements and data. You cannot place HTML or XHTML within this tag; it is flagged as an error by the browser.

However, browsers that do not support <script> process its contents as regular HTML, to the confusion of the user. For this reason, we recommend that you include the contents of the <script> tag inside HTML comments:

<script language="JavaScript">

<!--

   JavaScript statements go here

// -->

</script>

For browsers that ignore the <script> tag, the contents are masked by the comment delimiters <!-- and -->. JavaScript-enabled browsers, on the other hand, automatically recognize and interpret the JavaScript statements delimited by the comment tags. By using this skeleton for all your <script> tags, you can be sure that all browsers handle your document gracefully, if not completely.

Unfortunately, as we discuss in Chapter 16, script content for XHTML documents must be within a special CDATA declaration, rather than within comments. Hence, HTML browsers won't honor XHTML scripts, and vice versa. Our only recommendation at this point is to follow the popular browsers: write in HTML, but use as many of the features of XHTML as you can in preparation for the future.

You may include more than one <script> tag in a document, located in either the <head> or the <body>. The JavaScript-enabled browser executes the statements in order. Variables and functions defined within one <script> tag may be referenced by JavaScript statements in other <script> tags. In fact, one common JavaScript programming style is to use a single <script> in the document <head> to define common functions and global variables for the document and then to call those functions and reference their variables in other JavaScript statements sprinkled throughout the document.

<script>

Function:

Defines an executable script within a document

Attributes:

charset, defer, language, src, type

End tag:

</script>; never omitted

Contains:

scripts

Used in:

head_content, body_content

12.3.1.1 The language and type attributes

Use the language or type attribute in the <script> tag to declare the scripting language that you used to compose the contents of the tag. The language attribute is deprecated by the HTML 4 and XHTML standards in favor of the type attribute. Regrettably, the value for each attribute is different.

If you are using JavaScript ? by far the most common scripting language on the Web ? use language="JavaScript" or type="text/javascript". You may occasionally see the language value VBScript (text/vbscript for type), indicating that the enclosed code is written in Microsoft's Visual Basic Script.

With JavaScript, you may also use the language value "JavaScript 1.2", indicating that the enclosed script is written for browsers that support Version 1.2 of the language (most current browsers do). Versioning can be a problem, but it's not too severe. Netscape 2.0, for instance, supports JavaScript 1.0 but does not process scripts identified as "JavaScript 1.1". Then again, what proportion of your audience is running Netscape 2.0?

12.3.1.2 The src and charset attributes

For particularly large JavaScript programs and ones you reuse often, you should store the code in a separate file. In these cases, have the browser load that separate file through the src attribute. The value of the src attribute is the URL of the file containing the JavaScript program. The stored file should have a MIME type of application/x-javascript, but it will be handled automatically by a properly configured server if the filename suffix is .js.

For example:

<script language="JavaScript" src="http://www.kumquat.com/quatscript.js">

</script>

tells the <script>-able browser to load a JavaScript program named quatscript.js from the server. Although there are no <script> contents, the ending </script> still is required.

Used in conjunction with the src attribute, the charset attribute tells the browser the character set used to encode the JavaScript program. Its value is the name of any ISO standard character set encoding.

12.3.1.3 The defer attribute

Some JavaScript scripts create actual document content using the document.write method. If your scripts do not alter the contents of the document, add the defer attribute to the <script> tag to speed its processing. Since the browser knows that it can safely read the remainder of the document without executing your scripts, it defers interpretation of the script until after the document has been rendered for the user.

12.3.2 The <noscript> Tag

Use the <noscript> tag to tell users of browsers that do not support the <script> tag that they are missing something. You've already seen many examples of this type of tag. You know the drill...

<noscript>

Function:

Supplies content to <script>-challenged browsers

Attributes:

class, dir, id, lang, onClick, onDblClick, onKeyDown, onKeyPress, onKeyUp, onMouseDown, onMouseMove, onMouseOut, onMouseOver, onMouseUp, style, title

End tag:

</noscript>; never omitted

Contains:

body_content

Used in:

text

Very old, albeit <script>-able, browsers like Netscape 2 and Internet Explorer 3 blithely display the contents of the <noscript> tag, to the confusion of their users. Given the paucity of users of these browsers, we question the need, but there are ways to detect and handle <script>-challenged browsers, detailed in any good JavaScript book.

The <noscript> tag supports the 16 standard HTML 4/XHTML attributes: class and style for style management, lang and dir for language type and display direction, title and id for titling and naming the enclosed content, and the event attributes for user-initiated processing. [Section 3.6.1.1] [Section 3.6.1.2] [Section 4.1.1.4] [Section 4.1.1.4] [Section 8.1.1] [Section 8.3] [Section 12.3.3]

12.3.3 JavaScript Event Handlers

One of the most important features JavaScript provides is the ability to detect and react to events that occur while a document is loading, rendering, and being browsed by the user. The JavaScript code that handles these events may be placed within the <script> tag, but more commonly, it is associated with a specific tag via one or more special tag attributes.

For example, you might want to invoke a JavaScript function when the user passes the mouse over a hyperlink in a document. The JavaScript-aware browsers support a special "mouse over" event-handler attribute for the <a> tag, called onMouseOver, to do just that:

<a href="doc.html" onMouseOver="status='Click me!'; 

return true">

When the mouse passes over this example link, the browser executes the JavaScript statements. (Notice that the two JavaScript statements are enclosed in quotes and separated by a semicolon, and that single quotes surround the text-message portion of the first statement.)

While a complete explanation of this code is beyond our scope, the net result is that the browser places the message "Click me!" in the status bar of the browser window. Commonly, authors use this simple JavaScript function to display a more descriptive explanation of a hyperlink, in place of the often cryptic URL that the browser traditionally displays in the status window.

HTML and XHTML both support a rich set of event handlers through related "on"-event tag attributes. The value of any of the JavaScript event-handler attributes is a quoted string containing one or more JavaScript statements separated by semicolons. Extremely long statements can be broken across several lines, if needed. Care should also be taken in using entities for embedded double quotes in the statements, to avoid syntax errors when processing the attribute values.

12.3.3.1 Standard event handler attributes

Table 12-1 presents the current set of event handlers as tag attributes. Most are supported by the popular browsers, which also support a variety of nonstandard event handlers (tagged with asterisks in the table).

We put the event handlers into two categories: user- and document-related. The user-related ones are the mouse and keyboard events that occur when the user handles either device on the computer. User-related events are quite ubiquitous, appearing as standard attributes in nearly all the standard tags (even though they may not yet be supported by any browser), so we don't list their associated tags in Table 12-1. Instead, we'll tell you which tags do not accept these event attributes: <applet>, <base>, <basefont>, <bdo>, <br>, <font>, <frame>, <frameset>, <head>, <html>, <iframe>, <isindex>, <meta>, <param>, <script>, <style>, and <title>.

Table 12-1. Event handlers

Event handler

HTML/XHTML tags

onAbort*

<img>

onBlur

<a><area><body><button><frameset><input><label><select><textarea>

onChange

<input><select><textarea>

onClick

Most tags

onDblClick

Most tags

onError*

<img>

onFocus

<a><area><body><button><frameset><input><label><select><textarea>

onKeyDown

Most tags

onKeyPress

Most tags

onKeyUp

Most tags

onLoad

<body><frameset><img>*

onMouseDown

Most tags

onMouseMove

Most tags

onMouseOut

Most tags

onMouseOver

Most tags

onMouseUp

Most tags

onReset

<form>

onSelect

<input><textarea>

onSubmit

<form>

onUnload

<body><frameset>

Some events, however, occur rarely and with special tags. These relate to the special events and states that occur during the display and management of a document and its elements by the browser.

12.3.3.2 The mouse-related events

The onClick, onDblClick, onMouseDown, and onMouseUp attributes refer to the mouse button. The onClick event happens when the user presses down and then quickly releases the mouse button, unless the user then quickly clicks the mouse button for a second time. In that latter case, the onDblClick event gets triggered in the browser.

If you need to detect both halves of a mouse click as separate events, use onMouseDown and onMouseUp. When the user presses the mouse button, the onMouseDown event occurs. The onMouseUp event happens when the user releases the mouse button.

The onMouseMove, onMouseOut, and onMouseOver events happen when the user drags the mouse pointer. The onMouseOver event occurs when the mouse first enters the display region occupied by the associated HTML element. After entry, onMouseMove events are generated as the mouse moves about within the element. Finally, when the mouse exits the element, onMouseOut occurs.

For some elements, the onFocus event corresponds to onMouseOver, and onBlur corresponds to onMouseOut.

12.3.3.3 The keyboard events

Only three events relating to user keyboard actions currently are supported by the HTML 4 and XHTML standards: onKeyDown, onKeyUp, and onKeyPress,. The onKeyDown event occurs when the user depresses a key on the keyboard; onKeyUp happens when the key is released. The onKeyPress event is triggered when a key is pressed and released. Usually, you'll have handlers for either the up and down events or the composite key-press event, but not for both.

12.3.3.4 Document events

Most of the document-related event handlers relate to the actions and states of form controls. For instance, onReset and onSubmit happen when the user activates the respective reset or submit button. Similarly, onSelect and onChange occur as users interact with certain form elements. See Chapter 9 for a detailed discussion of these forms-related events.

There also are some document-related event handlers that occur when various document elements get handled by the browser. For instance, the onLoad event may happen when a frameset is complete or when the body of an HTML or XHTML document gets loaded and displayed by the browser. Similarly, onUnload occurs when a document is removed from a frame or window.

12.3.4 Javascript URLs

You can replace any conventional URL reference in a document with one or more JavaScript statements. The browser then executes the JavaScript code, rather than downloading another document, whenever the browser references the URL. The result of the last statement is taken to be the "document" referenced by the URL and is displayed by the browser accordingly. The result of the last statement is not the URL of a document; it is the actual content to be displayed by the browser.

To create a javascript URL, use javascript as the URL's protocol:

<a href="javascript:generate_document(  )">

In this example, the JavaScript function generate_document( ) gets executed whenever the user selects the hyperlink. The value returned by the function, presumably a valid HTML or XHTML document, is rendered and displayed by the browser.

It may be that the executed statement returns no value. In this case, the current document is left unchanged. For example, this javascript URL:

<a href="javascript:alert('Error!')">

pops up an alert dialog box and does nothing else. The document containing the hyperlink is still visible after the dialog box is displayed and dismissed by the user.

12.3.5 JavaScript Entities

Character entities in HTML and XHTML consist of an ampersand (&), an entity name or number, and a closing semicolon. For instance, to insert the ampersand character itself in a document text flow, use the character sequence &amp;. Similarly, JavaScript entities consist of an ampersand, one or more JavaScript statements enclosed in curly braces, and a closing semicolon. For example:

&{document.fgColor};

Multiple statements must be separated by semicolons within the curly braces. The value of the last (or only) statement is converted to a string and replaces the entity in the document.

Normally, entities can appear anywhere in an document. JavaScript entities, however, are restricted to values of tag attributes. This lets you write "dynamic tags" whose attributes are not known until the document is loaded and the JavaScript is executed. For example, this tag sets the text color of the document to the color value returned by the individual's favorite_color( ) function:

<body text=&{favorite_color(  )};>

12.3.6 The <server> Tag

The <server> tag is a strange beast. It is processed by the web server and never seen by the browser, so what you can do with this tag depends on the server you are using, not on the reader's browser.

Netscape's web servers (not to be confused with their browser) uses the <server> tag to let you to place JavaScript statements within a document that the server processes. The results of the executed JavaScript are then inserted into the document, replacing the <server> tag. A complete discussion of this so-called "server-side" JavaScript is completely beyond this book; we include this brief reference only to document the <server> tag.

<server> figs/n.gif

Function:

Defines server-side JavaScript

Attributes:

None

End tag:

</server>; never omitted

Contains:

JavaScript

Used in:

head_content

Like the <script> tag, the <server> tag contains JavaScript code. However, the latter tag and content code must appear inside the document <head>. It is extracted from the document and executed by the server when the document is requested for download.

Obviously, server-side JavaScript is tightly coupled to the server, not to the browser. To fully exploit this tag and the benefits of server-side JavaScript or other server-side programming languages, consult your web server's documentation.