Section 15.5. Traversing a Document


15.5. Traversing a Document

With the preceding overview of the W3C DOM under your belt, you are now ready to start using the DOM API. This section and the sections that follow it demonstrate how to traverse DOM trees, find specific elements within a document, modify document content, and add new content to a document.

As already discussed, the DOM represents an HTML document as a tree of Node objects. With any tree structure, one of the most common things to do is traverse the tree, examining each node of the tree in turn. Example 15-2 shows one way to do this. It is a JavaScript function that recursively examines a node and all its children, adding up the number of HTML tags (i.e., Element nodes) it encounters in the course of the traversal. Note the use of the childNodes property of a node. The value of this property is a NodeList object, which behaves (in JavaScript) like an array of Node objects. Thus, the function can enumerate all the children of a given node by looping through the elements of the childNodes[] array. By recursing, the function enumerates not just all children of a given node, but all nodes in the tree of nodes. Note that this function also demonstrates the use of the nodeType property to determine the type of each node.

Example 15-2. Traversing the nodes of a document

 <head> <script> // This function is passed a DOM Node object and checks to see if that node // represents an HTML tagi.e., if the node is an Element object. It // recursively calls itself on each of the children of the node, testing // them in the same way. It returns the total number of Element objects // it encounters. If you invoke this function by passing it the // Document object, it traverses the entire DOM tree. function countTags(n) {                         // n is a Node     var numtags = 0;                            // Initialize the tag counter     if (n.nodeType == 1 /*Node.ELEMENT_NODE*/)  // Check if n is an Element         numtags++;                              // Increment the counter if so     var children = n.childNodes;                // Now get all children of n     for(var i=0; i < children.length; i++) {    // Loop through the children         numtags += countTags(children[i]);      // Recurse on each one     }     return numtags;                             // Return the total } </script> </head> <!-- Here's an example of how the countTags() function might be used --> <body onload="alert('This document has ' + countTags(document) + ' tags')"> This is a <i>sample</i> document. 

Another point to notice about Example 15-2 is that the countTags() function it defines is invoked from the onload event handler so that it is not called until the document is completely loaded. This is a general requirement when working with the DOM: you cannot traverse or manipulate the document tree until the document has been fully loaded. (See Section 13.5.7. for further details on this requirement. Also see Example 17-7 for a utility function that allows multiple modules to register onload event handlers.)

In addition to the childNodes property, the Node interface defines a few other useful properties. firstChild and lastChild refer to the first and last children of a node, and nextSibling and previousSibling refer to adjacent siblings of a node. (Two nodes are siblings if they have the same parent node.) These properties provide another way to loop through the children of a node, demonstrated in Example 15-3. This example defines a function named getText() that finds all Text nodes at or beneath a specified node. It extracts and concatenates the textual content of the nodes and returns it as a single JavaScript string. The need for a utility function like this arises surprisingly frequently in DOM programming.

Example 15-3. Obtaining all text beneath a DOM node

 /**  * getText(n): Find all Text nodes at or beneath the node n.  * Concatenate their content and return it as a string.  */ function getText(n) {     // Repeated string concatenation can be inefficient, so we collect     // the value of all text nodes into an array, and then concatenate     // the elements of that array all at once.     var strings = [];     getStrings(n, strings);     return strings.join("");     // This recursive function finds all text nodes and appends     // their text to an array.     function getStrings(n, strings) {         if (n.nodeType == 3 /* Node.TEXT_NODE */)             strings.push(n.data);         else if (n.nodeType == 1 /* Node.ELEMENT_NODE */) {             // Note iteration with firstChild/nextSibling             for(var m = n.firstChild; m != null; m = m.nextSibling) {                 getStrings(m, strings);             }         }     } } 




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