Section 15.3. Legacy DOM: Document Object Collections


15.3. Legacy DOM: Document Object Collections

The list of Document object properties in the previous section omitted an important category of properties: document object collections. These array-valued properties are the heart of the legacy DOM. They are the properties that give you access to certain special elements of the document:


anchors[]

An array of Anchor objects that represent the anchors in the document. (An anchor is a named position in the document; it is created with an <a> tag that has a name attribute instead of an href attribute.) The name property of an Anchor object holds the value of the name attribute. See Part IV for complete details on the Anchor object.


applets[]

An array of Applet objects that represent the Java applets in the document. Applets are discussed in Chapter 23.


forms[]

An array of Form objects that represent the <form> elements in the document. Each Form object has its own collection property named elements[] that contains objects representing the form elements contained in the form. Form objects trigger an onsubmit event handler before the form is submitted. This handler can perform client-side form validation: if it returns false, the browser will not submit the form. The form[] collection is easily the most important one of the legacy DOM, and forms and form elements are the subject of Chapter 18.


images[]

An array of Image objects that represent the <img> elements in the document. The src property of an Image object is read/write, and assigning a URL to this property causes the browser to read and display a new image (in older browsers it must be the same size as the original). Scripting the src property of an Image object allows image-rollover effects and simple animations. These are covered in Chapter 22.


links[]

An array of Link objects that represent the hypertext links in the document. Hypertext links are created in HTML with <a> tags and occasionally with <area> tags in client-side image maps. The href property of a Link object corresponds to the href attribute of the <a> tag: it holds the URL of the link. Link objects also make the various components of a URL available through properties such as protocol, hostname, and pathname. In this way, the Link object is similar to the Location object discussed in Chapter 14. A Link object triggers an onmouseover event handler when the mouse pointer moves over it and an onmouseout handler when the pointer moves off. It triggers an onclick handler when the mouse is clicked over a link. If the event handler returns false, the browser will not follow the link. See Part IV for complete details on Link objects.

As their names imply, these properties are collections of all the links, images, forms, etc., that appear in a document. Their elements are in the same order as in the document source code. document.forms[0] refers to the first <form> tag in the document, and document.images[4] refers to the fifth <img> tag, for example.

The objects contained by these legacy DOM collections are scriptable, but it is important to understand that none of them allows you to alter the structure of the document. You can inspect and alter link destinations, read and write values from form elements, and even swap one image for another image, but you can't change the text of the document. Old browsers, such as Netscape 2, 3, and 4 and IE 3, were not able to reflow (or relayout) a document once it had been parsed and displayed. For this reason, the legacy DOM did not (and does not) allow document changes that require a reflow. For example, the legacy DOM includes an API for adding new <option> elements within a <select> element. It can do this because HTML forms display <select> elements as pull-down menus, and adding new items to such a menu does not alter the layout of rest of the form. There is no API in the legacy DOM for adding a new radio button to a form or adding a new row to a table, however, because changes like these would require a reflow.

15.3.1. Naming Document Objects

The problem with numerically indexed document object collections is that position-based indexes are brittle: small document changes that reorder document elements can break code that relies on their order. A more robust solution is to assign names to important document elements and to refer to those elements by name. In the legacy DOM, you do this with the name attribute of forms, form elements, images, applets, and links.

When the name attribute is present, its value is used to expose the corresponding object by name. So, for example, suppose an HTML document contains the following form:

 <form name="f1"><input type="button" value="Push Me"></form> 

Assuming that the <form> is the first one in the document, your JavaScript code can refer to the resulting Form object with any of the following three expressions:

 document.forms[0]     // Refer to the form by position within the document document.forms.f1     // Refer to the form by name as a property document.forms["f1"]  // Refer to the form by name as an array index 

In fact, setting the name attribute of a <form>, <img>, or <applet> (but not of an <a> tag) also makes the corresponding Form, Image, or Applet object (but not Link or Anchor object) accessible as a named property of the document object itself. Thus, you can also refer to the form as:

 document.f1 

The elements within a form may also be given names. If you set the name attribute of a form element, the object that represents that form element becomes accessible through a property of the Form object itself. So suppose you have a form that looks like this:

 <form name="shipping">   ...   <input type="text" name="zipcode">   ... </form> 

You can refer to the text input field element of this form with an intuitive syntax:

 document.shipping.zipcode 

One final note is necessary about the naming of document elements in the legacy DOM. What happens if two document elements have name attributes with the same value? If a <form> and <img> tag both have the name "n", for example, the document.n property becomes an array that holds references to both elements.

Typically, you should strive to ensure that your name attributes are unique so that this situation does not arise. It is common in one case, however. In HTML forms, convention dictates that groups of related radio buttons and checkboxes are given the same name. When you do this, that name becomes a property of the containing Form object, and the property value is an array that holds references to the various radio button or checkbox objects. You'll learn more about this in Chapter 18.

15.3.2. Event Handlers on Document Objects

To be interactive, an HTML document and the elements within it must respond to user events. You learned a bit about events and event handlers in Chapter 13, and you've seen several examples that use simple event handlers. There are many more examples of event handlers in this chapter because they are the link between document objects and JavaScript code.

I'll defer a complete discussion of events and event handlers until Chapter 17. For now, remember that event handlers are defined by attributes of HTML elements, such as onclick and onmouseover. The values of these attributes should be strings of JavaScript code. This code is executed whenever the specified event occurs on the HTML element.

Document objects accessed through collections such as document.links have properties that correspond to the attributes of the HTML tag. A Link object, for example, has an href tag that mirrors the HRef attribute of the <a> tag. This holds for event handlers as well. You can define an onclick event handler for a hyperlink either by setting the onclick attribute on the <a> tag or by setting the onclick property of the Link object. As another example, consider the onsubmit attribute of the <form> element. In JavaScript, the Form object has a corresponding onsubmit property. (Remember that HTML is not case-sensitive, and attributes can be written in uppercase, lowercase, or mixed case. In JavaScript, all event handler properties must be written in lowercase.)

In HTML, event handlers are defined by assigning a string of JavaScript code to an event-handler attribute. In JavaScript, however, they are defined by assigning a function to an event-handler property. Consider the following <form> and its onsubmit event handler:

 <form name="myform" onsubmit="return validateform();">...</form> 

In JavaScript, instead of using a string of JavaScript code that invokes a function and returns its result, simply assign the function directly to the event-handler property like this:

 document.myform.onsubmit = validateform; 

Note that there are no parentheses after the function name. This is because you don't want to invoke the function here; you just want to assign a reference to it.

See Chapter 17 for a complete discussion of event handlers.

15.3.3. Legacy DOM Example

Example 15-1 shows a listanchors() function that opens a new window and uses document.write() to output a list of all the anchors in the original document. Each entry in this list is a link with an event handler that causes the original window to scroll to the location of the specified anchor. The code in this example is particularly useful if you write your HTML documents so that all section headings are enclosed in anchors like this:

 <a name="sect14.6"><h2>The Anchor Object</h2></a> 

Note that the listanchors() function uses the Window.open() method. As shown in Chapter 14, browsers typically block pop-up windows unless they are created in response to a user action. Call listanchors() when the user clicks on a link or button; don't do it automatically when your web page loads.

Example 15-1. Listing all anchors

 /*  * listanchors.js: Create a simple table of contents with document.anchors[].  *  * The function listanchors() is passed a document as its argument and opens  * a new window to serve as a "navigation window" for that document. The new  * window displays a list of all anchors in the document. Clicking on any  * anchor in the list causes the document to scroll to that anchor.  */ function listanchors(d) {     // Open a new window     var newwin = window.open("", "navwin",                              "menubar=yes,scrollbars=yes,resizable=yes," +                              "width=500,height=300");     // Give it a title     newwin.document.write("<h1>Navigation Window: " + d.title + "</h1>");     // List all anchors     for(var i = 0; i < d.anchors.length; i++) {         // For each anchor object, determine the text to display.         // First, try to get the text between <a> and </a> using a         // browser-dependent property. If none, use the name instead.         var a = d.anchors[i];         var text = null;         if (a.text) text = a.text;                          // Netscape 4         else if (a.innerText) text = a.innerText;           // IE 4+         if ((text == null) || (text == '')) text = a.name;  // Default         // Now output that text as a link. The href property of this link         // is never used: the onclick handler does the work, setting the         // location.hash property of the original window to make that         // window jump to display the named anchor. See Window.opener,         // Window.location and Location.hash, and Link.onclick.         newwin.document.write('<a href="#' + a.name + '"' +                               ' onclick="opener.location.hash=\'' + a.name +                               '\'; return false;">');         newwin.document.write(text);         newwin.document.write('</a><br>');     }     newwin.document.close();  // Never forget to close the document! } 




JavaScript. The Definitive Guide
JavaScript: The Definitive Guide
ISBN: 0596101996
EAN: 2147483647
Year: 2004
Pages: 767

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net