15.7. Modifying a DocumentTraversing the nodes of a document can be useful, but the real power of the Core DOM API lies in the features that allow you to use JavaScript to dynamically modify documents. The following examples demonstrate the basic techniques of modifying documents and illustrate some of the possibilities. Example 15-5 includes a JavaScript function named sortkids(), a sample document, and an HTML button that, when pressed, calls the sortkids() function, passing it the ID of a <ul> tag. The sortkids() function finds the element children of the specified node, sorts them based on the text they contain, and rearranges them in the document (using appendChild()) so that they appear in alphabetical order. Example 15-5. Alphabetizing the elements of a list
The result of Example 15-5, illustrated in Figure 15-3, is that when the user clicks the button, the list items are alphabetized. Figure 15-3. A list before and after being sortedNote that Example 15-5 copied the nodes it was going to sort to a separate array. This enables you to easily sort the array but has another benefit as well. The NodeList objects that are the value of the childNodes property and that are returned by getElementsByTagName() are "live": any changes to the document are immediately reflected in the NodeList. This can be a source of difficulty if you insert or delete nodes from a list while iterating through that list. Thus it is often safest to take a "snapshot" of the nodes, by transferring them to a true array before looping through them. Example 15-5 altered the structure of a document by rearranging elements. Example 15-6 alters the content of a document by changing its text. This example defines a function upcase() that recursively descends from a specified Node and converts the content of any Text nodes it finds to uppercase. Example 15-6. Converting document content to uppercase
Example 15-6 simply sets the data property of each text node it encounters. It is also possible to append, insert, delete, or replace text within a Text node with the appendData(), insertData(), deleteData(), and replaceData() methods. These methods are not directly defined by the Text interface but instead are inherited by Text from CharacterData. You can find more information about them under CharacterData in Part IV. In Example 15-5, you rearranged document elements but kept them within the same parent element. Note, however, that the DOM API allows nodes in the document tree to be moved freely within the tree (only within the same document, however). Example 15-7 demonstrates this by defining a function named embolden() that replaces a specified node with a new element (created with the createElement() method of the Document object) that represents an HTML <b> tag and "reparents" the original node as a child of the new <b> node. In an HTML document, this causes any text within the node or its descendants to be displayed in boldface. Example 15-7. Reparenting a node to a <b> element
15.7.1. Modifying AttributesIn addition to modifying documents by altering text and reparenting or otherwise rearranging nodes, it is also possible to make substantial changes to a document simply by setting attribute values on document elements. One way to do this is with the element.setAttribute() method. For example: var headline = document.getElementById("headline"); // Find named element headline.setAttribute("align", "center"); // Set align='center' The DOM elements that represent HTML attributes define JavaScript properties that correspond to each of their standard attributes (even deprecated attributes such as align), so you can also achieve the same effect with this code: var headline = document.getElementById("headline"); headline.align = "center"; // Set alignment attribute. As shown in Chapter 16, you can achieve a whole world of useful effects by altering the CSS style properties of HTML elements in this way. Doing so does not alter the document structure or content, but instead alters its presentation. 15.7.2. Working with Document FragmentsA DocumentFragment is a special type of node that does not appear in a document itself but serves as a temporary container for a sequential collection of nodes and allows those nodes to be manipulated as a single object. When a DocumentFragment is inserted into a document (using any of the appendChild(), insertBefore(), or replaceChild() methods of the Node object), it is not the DocumentFragment itself that is inserted, but each of its children. You can create a DocumentFragment with document.createDocumentFragment(). You can add nodes to a DocumentFragment with appendChild() or any of the related Node methods. Then, when you are ready to add those nodes to the document, add the DocumentFragment itself. After you do this, the fragment is empty and cannot be reused unless you first add new children to it. Example 15-8 demonstrates this process. It defines a reverse() function that uses a DocumentFragment as a temporary container while reversing the order of the children of a Node. Example 15-8. Using a DocumentFragment
|