12.2 Embedding JavaScript in HTMLClient-side JavaScript code is embedded within HTML documents in a number of ways:
The following sections document each of these JavaScript embedding techniques in more detail. Together, they explain all the ways to include JavaScript in web pages -- that is, they explain the allowed structure of JavaScript programs on the client side. 12.2.1 The <script> TagClient-side JavaScript scripts are part of an HTML file and are coded within <script> and </script> tags. You may place any number of JavaScript statements between these tags; they are executed in order of appearance, as part of the document loading process. <script> tags may appear in either the <head> or <body> of an HTML document. A single HTML document may contain any number of nonoverlapping pairs of <script> and </script> tags. These multiple, separate scripts are executed in the order in which they appear within the document. While separate scripts within a single file are executed at different times during the loading and parsing of the HTML file, they constitute part of the same JavaScript program: functions and variables defined in one script are available to all scripts that follow in the same file. For example, you can have the following script somewhere in an HTML page: <script>var x = 1;</script> Later on in the same HTML page, you can refer to x, even though it's in a different script block. The context that matters is the HTML page, not the script block: <script>document.write(x);</script> The document.write( ) method is an important and commonly used one. When used as shown here, it inserts its output into the document at the location of the script. When the script finishes executing, the HTML parser resumes parsing the document and starts by parsing any text produced with document.write( ). Example 12-1 shows a sample HTML file that includes a simple JavaScript program. Note the difference between this example and many of the code fragments shown earlier in this book: this one is integrated with an HTML file and has a clear context in which it runs. Note also the use of a language attribute in the <script> tag. This is explained in the next section. Example 12-1. A simple JavaScript program in an HTML file<html> <head> <title>Today's Date</title> <script language="JavaScript"> // Define a function for later use function print_todays_date( ) { var d = new Date( ); // Get today's date and time document.write(d.toLocaleString( )); // Insert it into the document } </script> </head> <body> The date and time are:<br> <script language="JavaScript"> // Now call the function we defined above print_todays_date( ); </script> </body> </html> 12.2.1.1 The language and type attributesAlthough JavaScript is by far the most commonly used client-side scripting language, it is not the only one. In order to tell a web browser what language a script is written in, the <script> tag has an optional language attribute. Browsers that understand the specified scripting language run the script; browsers that do not know the language ignore it. If you are writing JavaScript code, use the language attribute as follows: <script language="JavaScript"> // JavaScript code goes here </script> If, for example, you are writing a script in Microsoft's Visual Basic Scripting Edition language,[2] you would use the attribute like this:
<script language="VBScript"> ' VBScript code goes here (' is a comment character like // in JavaScript) </script> JavaScript is the default scripting language for the Web, and if you omit the language attribute, both Netscape and Internet Explorer will assume that your scripts are written in JavaScript. The HTML 4 specification standardizes the <script> tag, but it deprecates the language attribute because there is no standard set of names for scripting languages. Instead, the specification prefers the use of a type attribute that specifies the scripting language as a MIME type. Thus, in theory, the preferred way to embed a JavaScript script is with a tag that looks like this: <script type="text/javascript"> In practice, the language attribute is still better supported than this new type attribute. The HTML 4 specification also defines a standard (and useful) way to specify the default scripting language for an entire HTML file. If you plan to use JavaScript as the only scripting language in a file, simply include the following line in the <head> of the document: <meta http-equiv="Content-Script-Type" content="text/javascript"> If you do this, you can safely use JavaScript scripts without specifying the language or type attributes. Since JavaScript is the default scripting language, those of us who program with it never really need to use the language attribute to specify the language in which a script is written. However, there is an important secondary purpose for this attribute: it can also be used to specify what version of JavaScript is required to interpret a script. When you specify the language="JavaScript" attribute for a script, any JavaScript-enabled browser will run the script. Suppose, however, that you have written a script that uses the exception-handling features of JavaScript 1.5. To avoid syntax errors in browsers that do not support this version of the language, you could embed your script with this tag: <script language="JavaScript1.5"> If you do this, only browsers that support JavaScript 1.5 (and its exception-handling features) will run the script; any others will ignore it. The use of the string "JavaScript1.2" in the language attribute deserves special mention. When Netscape 4 was being prepared for release, it appeared that the emerging ECMA-262 standard would require some incompatible changes to certain features of the language. To prevent these incompatible changes from breaking existing scripts, the designers of JavaScript at Netscape took the sensible precaution of implementing the changes only when "JavaScript1.2" was explicitly specified in the language attribute. Unfortunately, the ECMA standard was not finalized before Netscape 4 was released, and after the release, the proposed incompatible changes to the language were removed from the standard. Thus, specifying language="JavaScript1.2" makes Netscape 4 behave in ways that are not compatible with previous browsers or with the ECMA specification. (See Section 11.6, for complete details on these incompatibilities.) For this reason, you may want to avoid specifying "JavaScript1.2" as a value for the language attribute. 12.2.1.2 The </script> tagYou may at some point find yourself writing a script that uses the document.write( ) method to output a script into some other browser window or frame. If you do this, you'll need to write out a </script> tag to terminate the script you are writing. You must be careful, though -- the HTML parser makes no attempt to understand your JavaScript code, and if it sees the string "</script>" in your code, even if it appears within quotes, it assumes that it has found the closing tag of the currently running script. To avoid this problem, simply break up the tag into pieces and write it out using an expression like "</" + "script>": <script> f1.document.write("<script>"); f1.document.write("document.write('<h2>This is the quoted script</h2>')"); f1.document.write("</" + "script>"); </script> Alternatively, you can escape the / in </script> with a backslash: f1.document.write("<\/script>"); 12.2.1.3 The defer attributeThe HTML 4 standard defines an attribute of the <script> tag that is not yet in common use but is nonetheless important. As I mentioned briefly earlier, a script may call the document.write( ) method to dynamically add content to a document. Because of this, when the HTML parser encounters a script, it must stop parsing the document and wait for the script to execute. If you write a script that does not produce any document output -- for example, a script that defines a function but never calls document.write( ) -- you may use the defer attribute in the <script> tag as a hint to the browser that it is safe for it to continue parsing the HTML document and defer execution of the script until it encounters a script that cannot be deferred. Doing this may result in improved performance in browsers that take advantage of the defer attribute. Note that defer does not have a value; it simply must be present in the tag: <script defer> // Any JavaScript code that does not call document.write( ) </script> 12.2.2 Including JavaScript FilesAs of JavaScript 1.1, the <script> tag supports a src attribute. The value of this attribute specifies the URL of a file containing JavaScript code. It is used like this: <script src="../../javascript/util.js"></script> A JavaScript file typically has a .js extension and contains pure JavaScript, without <script> tags or any other HTML. A <script> tag with the src attribute specified behaves exactly as if the contents of the specified JavaScript file appeared directly between the <script> and </script> tags. Any code that does appear between these tags is ignored by browsers that support the src attribute (although it is still executed by browsers such as Netscape 2 that do not recognize the attribute). Note that the closing </script> tag is required even when the src attribute is specified and there is no JavaScript between the <script> and </script> tags. There are a number of advantages to using the src tag:
12.2.3 Event HandlersJavaScript code in a script is executed once, when the HTML file that contains it is read into the web browser. A program that uses only this sort of static script cannot dynamically respond to the user. More dynamic programs define event handlers that are automatically invoked by the web browser when certain events occur -- for example, when the user clicks on a button within a form. Because events in client-side JavaScript originate from HTML objects (such as buttons), event handlers are defined as attributes of those objects. For example, to define an event handler that is invoked when the user clicks on a checkbox in a form, you specify the handler code as an attribute of the HTML tag that defines the checkbox: <input type="checkbox" name="opts" value="ignore-case" onclick="ignore-case = this.checked;" > What's of interest to us here is the onclick attribute.[3] The string value of the onclick attribute may contain one or more JavaScript statements. If there is more than one statement, the statements must be separated from each other with semicolons. When the specified event -- in this case, a click -- occurs on the checkbox, the JavaScript code within the string is executed.
While you can include any number of JavaScript statements within an event handler definition, a common technique when more than one or two simple statements are required is to define the body of an event handler as a function between <script> and </script> tags. Then you can simply invoke this function from the event handler. This keeps most of your actual JavaScript code within scripts and reduces the need to mingle JavaScript and HTML. We'll cover events and event handlers in much more detail in Chapter 19, but you'll see them used in a variety of examples before then. Chapter 19 includes a comprehensive list of event handlers, but these are the most common:
For a realistic example of the use of event handlers, take another look at the interactive loan-payment script in Example 1-3. The HTML form in this example contains a number of event handler attributes. The body of these handlers is simple: they simply call the calculate( ) function defined elsewhere within a <script>. 12.2.4 JavaScript in URLsAnother way that JavaScript code can be included on the client side is in a URL following the javascript: pseudoprotocol specifier. This special protocol type specifies that the body of the URL is arbitrary JavaScript code to be run by the JavaScript interpreter. If the JavaScript code in a javascript: URL contains multiple statements, the statements must be separated from one another by semicolons. Such a URL might look like this: javascript:var now = new Date( ); "<h1>The time is:</h1>" + now; When the browser loads one of these JavaScript URLs, it executes the JavaScript code contained in the URL and uses the string value of the last JavaScript statement as the contents of the new document to display. This string value may contain HTML tags and is formatted and displayed just like any other document loaded into the browser. JavaScript URLs may also contain JavaScript statements that perform actions but return no value. For example: javascript:alert("Hello World!") When this sort of URL is loaded, the browser executes the JavaScript code, but because there is no value to display as the new document, it does not modify the currently displayed document. Often, we want to use a javascript: URL to execute some JavaScript code without altering the currently displayed document. To do this, you must be sure that the last statement in the URL has no return value. One way to ensure this is to use the void operator to explicitly specify an undefined return value. Simply use the statement void 0; at the end of your javascript: URL. For example, here is a URL that opens a new, blank browser window without altering the contents of the current window: javascript:window.open("about:blank"); void 0; Without the void operator in this URL, the return value of the Window.open( ) method call would be converted to a string and displayed, and the current document would be overwritten by a document that appears something like this: [object Window] You can use a javascript: URL anywhere you'd use a regular URL. One important way to use this syntax is to type it directly into the Location field of your browser, where you can test arbitrary JavaScript code without having to open your editor and create an HTML file containing the code. javascript: URLs can be used in bookmarks, where they form useful mini-JavaScript programs, or "bookmarklets," that can be easily launched from a menu or toolbar of bookmarks. javascript: URLs can also be used as the href value of a hyperlink. When the user clicks on such a link, the specified JavaScript code is executed. Or, if you specify a javascript: URL as the value of the action attribute of a <form> tag, the JavaScript code in the URL is executed when the user submits the form. In these contexts, the javascript: URL is essentially a substitute for an event handler. There are a few circumstances where a javascript: URL can be used with objects that do not support event handlers. For example, the <area> tag does not support an onclick event handler on Windows platforms in Netscape 3 (though it does in Netscape 4). So, if you want to execute JavaScript code when the user clicks on a client-side image map in Netscape 3, you must use a javascript: URL. 12.2.5 JavaScript in Nonstandard ContextsBoth Netscape and Microsoft have implemented proprietary extensions in their browsers, and you may occasionally see JavaScript code in a context other than those described here. For example, Internet Explorer allows you to define event handlers in a <script> tag that uses special for and event attributes. Netscape 4 allows you to use JavaScript as an alternative syntax for defining CSS style sheets within a <style> tag. Netscape 4 also extends the HTML entity syntax and allows JavaScript to appear within entities (but only within the values of HTML attributes). This can result in HTML that looks like this: <table border="&{getBorderWidth( )};"> Finally, Netscape 4 also supports a form of conditional comment based on this JavaScript entity syntax. Note that Netscape 6 and the Mozilla browser on which it is based no longer support these nonstandard uses of JavaScript. |