Team LiB
Previous Section Next Section

Adding JavaScript to XHTML Documents

As suggested by the previous example, the <script> element is commonly used to add script to a document. However, there are four standard ways to include script in an (X)HTML document:

Note that some older browser versions support other non-standard ways to include scripts in your page, such as Netscape 4’s entity inclusion. However, we avoid discussing these in this edition since today these methods are interesting only as historical footnotes and are not used. The following section presents the four common methods for combining markup and JavaScript, and should be studied carefully by all readers before tackling the examples in the rest of the book.

The <script> Element

The primary method to include JavaScript within HTML or XHTML is the <script> element. A script-aware browser assumes that all text within the <script> tag is to be interpreted as some form of scripting language; by default this is generally JavaScript. However, it is possible for the browser to support other scripting languages such as VBScript, which is supported by the Internet Explorer family of browsers. Traditionally, the way to indicate the scripting language in use is to specify the language attribute for the tag. For example,

<script language="JavaScript">

</script>

is used to indicate the enclosed content is to be interpreted as JavaScript. Other values are possible; for example,

<script language="VBS">

</script>

would be used to indicate VBScript is in use. A browser should ignore the contents of the <script> element when it does not understand the value of its language attribute.

Tip 

Be very careful setting the language attribute for <script>. A simple typo in the value will usually cause the browser to ignore any content within.

According to the W3C HTML syntax, however, the language attribute should not be used. Instead the type attribute should be set to indicate the MIME type of the language in use. JavaScript’s MIME type is generally agreed upon to be "text/javascript", so you use

<script type="text/javascript">
</script>
Note 

The “W3C” is the World Wide Web Consortium, the international body responsible for standardizing Web-related technologies such as HTML, XML, and CSS. The W3C Web site is www.w3.org, and is the canonical place to look for Web standards information.

Practically speaking, the type attribute is not as common in markup as the language attribute, which has some other useful characteristics, particularly to conditionally set code depending on the version of JavaScript supported by the browser. This technique will be discussed in Chapter 22 and illustrated throughout the book. To harness the usefulness of the language attribute while respecting the standards of the <script> element, you might consider using both:

<script language="JavaScript" type="text/javascript">

</script>

Unfortunately, this doesn’t work well in some cases. First off, your browser will likely respect the type attribute over language so you will lose any of the latter attribute. Second, the page will not validate as conforming to the XHTML standard because, as we’ve said, the language attribute is non-standard. Following the standard, using the type attribute is the best bet unless you have a specific reason to use the non-standard language attribute.

Note 

Besides using the type attribute for <script>, according to HTML specifications you could also specify the script language in use document-wide via the <meta> element, as in <meta http-equiv="Content-Script-Type" content="text/javascript" />. Inclusion of this statement within the <head> element of a document would alleviate any requirement of putting the type attribute on each <script> element.

Using the <script> Element

You can use as many <script> elements as you like. Documents will be read and possibly executed as they are encountered, unless the execution of the script is deferred for later. (The reasons for deferring script execution will be discussed in a later section.) The next example shows the use of three simple printing scripts that run one after another.

<!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" lang="en">
<head>
<title>JavaScript and the Script Tag</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
</head>
<body>
<h1>Ready start</h1>
<script type="text/javascript">
      alert("First Script Ran");
</script>
<h2>Running...</h2>
<script type="text/javascript">
      alert("Second Script Ran");
</script>
<h2>Keep running</h2>
<script type="text/javascript">
      alert("Third Script Ran");
</script>
<h1>Stop!</h1>
</body>
</html>

Try this example in various browsers to see how the script runs. You may notice that with some browsers the HTML is written out as the script progresses, with others not.

This shows that the execution model of JavaScript does vary from browser to browser.

Script in the <head>

A special location for the <script> element is within the <head> tag of an (X)HTML document. Because of the sequential nature of Web documents, the <head> is always read in first, so scripts located here are often referenced later on by scripts in the <body> of the document. Very often scripts within the <head> of a document are used to define variables or functions that may be used later on in the document. The following example shows how the script in the <head> defines a function that is later called by script within the <script> block later in the <body> of the document.

<!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" lang="en">
<head>
<title>JavaScript in the Head</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<script type="text/javascript">
function alertTest() 
{
  alert("Danger! Danger! JavaScript Ahead");
}
</script>
</head>
<body>
<h2 align="center">Script in the Head</h2>
<hr />
<script type="text/javascript">
 alertTest();
</script>
</body>
</html>

Script Hiding

Most browsers tend to display the content enclosed by any tags they don’t understand, so it is important to mask code from browsers that do not understand JavaScript. Otherwise, the JavaScript would show up as text in the page for these browsers. Figure 1-3 shows an example Web page viewed by non-JavaScript supporting browsers without masking. One easy way to mask JavaScript is to use HTML comments around the script code.

Click To expand
Figure 1-3: JavaScript code may print on the screen if not masked.

For example:

<script type="text/javascript">
<!-- 

  put your JavaScript here

//-->
</script>
Note 

This masking technique is similar to the method used to hide CSS markup, except that the final line must include a JavaScript comment to mask out the HTML close comment. The reason for this is that the characters – and > have special meaning within JavaScript.

While the comment mask is very common on the Web, it is actually not the appropriate way to do it in strict XHTML. Given that XHTML is an XML-based language, many of the characters found in JavaScript, such as > or &, have special meaning, so there could be trouble with the previous approach. According to the strict XHTML specification, you are supposed to hide the contents of the script from the XHTML-enforcing browser using the following technique:

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

This approach does not work in any but the strictest XML-enforcing browsers. It generally causes the browser to ignore the script entirely or throw errors, so authors have the option of using linked scripts or traditional comment blocks, or simply ignoring the problem of down-level browsers. Most Web developers interested in strict XHTML conformance use linked scripts; developers only interested in HTML (or not interested in standards at all) generally use the traditional comment-masking approach. We’ve chosen the latter approach as it is the most widely used on the Web today.

The <noscript> Element

In the situation that a browser does not support JavaScript or that JavaScript is turned off, you should provide an alternative version or at least a warning message telling the user what happened. The <noscript> element can be used to accomplish this very easily. All JavaScript-aware browsers should ignore the contents of <noscript> unless scripting is off. Browsers that aren’t JavaScript-aware will show the enclosed message (and they’ll ignore the contents of the <script> if you’ve remembered to HTML-comment it out). The following example illustrates a simple example of this versatile element’s use.

<!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" lang="en">
<head>
<title>noscript Demo</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
</head>
<body>
<script type="text/javascript">
<!--
      alert("Your JavaScript is on!");
//-->
</script>
<noscript>
      <em>Either your browser does not support JavaScript or it
         is currently disabled.</em>
</noscript>
</body>
</html>

Figure 1-4 shows a rendering in three situations: first a browser that does not support JavaScript, then a browser that does support it but has JavaScript disabled, and finally a modern browser with JavaScript turned on.

Click To expand
Figure 1-4: Use <noscript> to handle browsers with no JavaScript.

One interesting use of the <noscript> element might be to redirect users automatically to a special error page using a <meta> refresh if they do not have scripting enabled in the browser or are using a very old browser. The following example shows how this might be done.

<!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" lang="en">
<head>
<title>noscript Redirect Demo</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<!--  warning example does not validate -->
<noscript>
      <meta http-equiv="Refresh" content="0;URL=/errors/noscript.html" />
</noscript>
</head>
<body>
<script type="text/javascript">
<!--
 document.write("Congratulations! If you see this you have JavaScript.");
//-->
</script>
<noscript>
   <h2>Error: JavaScript required</h2>
   <p>Read how to <a href="/errors/noscript.html">rectify this problem</a>.</p>
</noscript>
</body>
</html>

Unfortunately, according to the XHTML specification, the <noscript> tag is not supposed to be found in the <head>, so this example will not validate. This seems more an oversight than an error considering that the <script> tag is allowed in the <head>. However, for those looking for strict markup, this useful technique is not appropriate, despite the fact that it could allow for robust error handling of down-level browsers. More information about defensive programming techniques like this one is found in Chapter 23.

Event Handlers

To make a page more interactive, you can add JavaScript commands that wait for a user to perform a certain action. Typically, these scripts are executed in response to form actions and mouse movements. To specify these scripts, we set up various event handlers, generally by setting an attribute of an (X)HTML element to reference a script. We refer to these attributes collectively as event handlers—they perform some action in response to a user interface event. All of these attributes start with the word “on,” indicating the event in response to which they’re executed, for example, onclick, ondblclick, and onmouseover. This simple example shows how a form button would react to a click:

<!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" lang="en">
<head>
<title>JavaScript and HTML Events Example</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
</head>
<body>
<form action="#" method="get">
<input type="button" value="press me" 
       onclick="alert('Hello from JavaScript!');" />
</form>
</body>
</html>
Note 

When writing traditional HTML markup, developers would often mix case in the event handlers, for example, onClick="". This mixed casing made it easy to pick them out from other markup and had no effect other than improving readability. Remember, these event handlers are part of HTML and would not be case sensitive, so onClick, ONCLICK, onclick, or even oNcLiCK are all valid. However, XHTML requires all lowercase, so you should lowercase event handlers regardless of the tradition.

By putting together a few <script> tags and event handlers, you can start to see how scripts can be constructed. The following example shows how a user event on a form element can be used to trigger a JavaScript defined in the <head> of a document.

<!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" lang="en">
<head>
<title>Event Trigger Example</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<script type="text/javascript">
<!--
function alertTest() 
{
  alert("Danger! Danger!");
}
//-->
</script>
</head>
<body>
<div align="center">
<form action="#" method="get">
<input type="button" value="Don’t push me!"
      onclick="alertTest();" />
</form>
</div>
</body>
</html>

A rendering of the previous example is shown in Figure 1-5.

Click To expand
Figure 1-5: Scripts can interact with users.

You may wonder which (X)HTML elements have event handler attributes. Beginning with the HTML 4.0 specification, nearly every tag (generally, all that have a visual display) should have one of the core events, such as onclick, ondblclick, onkeydown, onkeypress, onkeyup, onmousedown, onmousemove, onmouseover, and onmouseout, associated with it. For example, even though it might not make much sense, you should be able to specify that a paragraph can be clicked using markup and script like this:

<p onclick="alert('Under HTML 4 you can!')">Can you click me?</p>

Of course, many older browsers, even from the 4.x generation, won’t recognize event handlers for many HTML elements, such as paragraphs. Most browsers, however, should understand events such as the page loading and unloading, link presses, form fill-in, and mouse movement. The degree to which each browser supports events and how they are handled varies significantly, but the core events are widely supported among modern browsers. Many examples throughout the book will examine how events are handled and an in-depth discussion on browser differences for event handling can be found in Chapter 11.

Linked Scripts

A very important way to include a script in an HTML document is by linking it via the src attribute of a <script> tag. The example here shows how we might put the function from the previous example in a linked JavaScript file.

<!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" lang="en">
<head>
<title>Event Trigger Example using Linked Script</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<script type="text/javascript" src="danger.js"></script>
</head>
<body>
<div align="center">
<form action="#" method="get">
<input type="button" value="Don't push me!" onclick="alertTest();" />
</form>
</div>
</body>
</html>

Notice that the src attribute is set to the value "danger.js". This value is a URL path to the external script. In this case, it is in the same directory, but it could have just as easily been an absolute URL such as http://www.javascriptref.com/scripts/danger.js. Regardless of the location of the file, all it will contain is the JavaScript code to run—no HTML or other Web technologies. So in this example, the file danger.js could contain the following script:

function alertTest()  
{
  alert("Danger! Danger!");
}

The benefit of script files that are external is that they separate the logic, structure, and presentation of a page. With an external script it is possible to easily reference the script from many pages in a site. This makes maintenance of your code easier because you only have to update code common to many pages in one place (the external script file) rather than on every page. Furthermore, a browser can cache external scripts so their use effectively speeds up Web site access by avoiding extra download time retrieving the same script.

Tip 

Consider putting all the scripts used in a site in a common script directory similar to how images are stored in an images directory. This will ensure proper caching, keep scripts separated from content, and start a library of common code for use in a site.

While there are many benefits to using external scripts, they are often not used because of some of their potential downsides. An uncommon reason is that not all JavaScript-aware browsers support linked scripts. Fortunately, this problem is mostly related to extremely old browsers, specifically Netscape 2 and some Internet Explorer 3 releases. These are extremely uncommon browsers these days, so this isn’t much of a concern unless you’re hyper-conscious of backward-compatibility.

The primary challenge with external scripts has to do with browser loading. If an external script contains certain functions referenced later on, particularly those invoked by user activities, programmers must be careful not to allow them to be invoked until they have been downloaded or error dialogs may be displayed. That is, there’s no guarantee as to when an externally linked script will be loaded by the browser. Usually, they’re loaded very quickly, in time for any JavaScript in the page to reference them properly. But if the user is connecting via a very slow connection, or if script calling functions defined in the external script are executed immediately, they might not have loaded yet.

Fortunately, most of the problems with external scripts can be alleviated with good defensive programming styles, as demonstrated throughout the book. Chapter 23 covers specific techniques in detail. However, if stubborn errors won’t seem to go away and external scripts are in use, a good suggestion is to move the code to be included directly within the HTML file.

Tip 

When using external .js files, make sure that your Web server is set up to map the file extension .js to the MIME type text/javascript. Most Web servers have this MIME type set by default, but if you are experiencing problems with linked scripts this could be the cause.

JavaScript Pseudo-URL

In most JavaScript-aware browsers, it is possible to invoke a script using the JavaScript pseudo-URL. A pseudo-URL like javascript: alert('hello') would invoke a simple alert displaying “hello” when typed directly in the browser’s address bar, as shown here:

Click To expand
Note 

Under some browsers, notably versions 4 and above of Netscape, it is possible to gain access to a JavaScript console when typing in the URL javascript: by itself. Other browsers have a console that can be accessed to view errors and test code. However, Internet Explorer does not provide such direct access to the console, which can be used both for debugging and for testing the values of scripts. Examples of the JavaScript console are shown in Figure 1-6.

Click To expand
Click To expand
Figure 1-6: JavaScript console used for debugging and testing

One very important way to use the JavaScript pseudo-URL is within a link, as demonstrated here:

<a href="javascript: alert('hello I am a pseudo-URL script');">Click
to invoke</a>
Click To expand

The pseudo-URL inclusion can be used to trigger any arbitrary amount of JavaScript, so

<a href="javascript: x=5;y=7;alert('The sum = '+(x+y));">Click to invoke</a>

is just as acceptable as invoking a single function or method. Some developers have found this quite useful and have designed functions to be executed on pages and saved as bookmarks. When these javascript: links are added as “Favorites” or “Bookmarks” in your browser, they can be clicked in order to carry out a specific task. These scripts, typically dubbed bookmarklets or favlets, are used to resize windows, validate pages, and perform a variety of useful developer-related tasks.

Note 

Running JavaScript via the URL in the form of a bookmark does have some security considerations. Since bookmarklets stored in your browser execute in the context of the current page, a malicious bookmarklet could be used to steal cookies for the current site. For this reason, only install bookmarklets from sites you trust, or only after examining their code.

The javascript: URL does have a problem, of course, when used in a browser that does not support JavaScript. In such cases, the browser will display the link appropriately but the user will not be able to cause the link to do anything, which would certainly be very frustrating. Designers relying on pseudo-URLs should make sure to warn users using the <noscript> element, as shown here:

<noscript>
<strong><em>Warning:</em> This page contains links that use JavaScript 
and your browser either has JavaScript disabled or does not support this
 technology.</strong>
</noscript>

However, this assumes that the user sees the message. A more defensive coding style might be to recode the initial pseudo-URL link as follows.

<a href="/errors/noscript.html"onclick=" alert('hello I am a pseudo-URL 
script');return false;">Click to invoke</a>

In this case, with the script on the onclick, the JavaScript is run when the link is clicked and return false kills the page load. However, with script off, the code will not run and instead the user will be sent to the error page specified by the href attribute. While the javascript: pseudo-URL does have some limitations, it is commonly found in all major implementations of the language and used by many developers. It is definitely better, however, to avoid using the pseudo-URL technique and replace it with the defensive onclick code presented. Now before concluding the chapter, let’s take a brief look at what JavaScript is used for, where it came from, and where it is likely going.


Team LiB
Previous Section Next Section