Chapter 10

Manipulating Documents with the DOM

In This Chapter

arrow Getting to know the DOM (Document Object Model)

arrow Working with nodes

arrow Moving around the tree

arrow Selecting elements

No object is mysterious. The mystery is your eye.

— Elisabeth Bowen

Understanding the DOM is key to being able to manipulate the text or HTML in a web page. Using the DOM, you can create animations, update data without refreshing web pages, move objects around in a browser, and much more!

Understanding the DOM

The Document Object Model is the interface for JavaScript to talk to and work with HTML documents inside of browser windows. The DOM can be visualized as an inverted tree, with each part of the HTML document branching off of its containing part.

Listing 10-1 is the markup for a web page. The DOM representation is shown in Figure 10-1.

image

Figure 10-1: A representation of the Document Object Model for Listing 10-1.

Listing 10-1: An HTML Document

<html>
<head>
 <title>Bob's Appliances</title>
</head>
<body>
 <header>
   <img src="logo.gif" width="100" height="100" alt="Site Logo">
 </header>
 <div>
   <h1>Welcome to Bob's</h1>
   <p>The home of quality appliances</p>
 </div>
 <footer>
   copyright &copy; Bob
 </footer>
</body>
</html>

A DOM tree is made up of individual components, called nodes. The main node, from which every other node springs, is called the document node. The node under the document node is the root element node. For HTML documents, the root node is HTML. After the root node, every element, attribute, and piece of content in the document is represented by a node in the tree that comes from another node in the tree.

The DOM has several different types of nodes:

  • Document node: The entire HTML document is represented in this node
  • Element nodes: The HTML elements
  • Attribute nodes: The Attributes associated with elements
  • Text nodes: The text content of elements
  • Comment nodes: The HTML comments in a document

Node Relationships

HTML DOM trees resemble family trees in the hierarchical relationship between nodes. In fact, the technical terms used to describe relationships between nodes in a tree take their names from familial relationships.

  • Every node, except the root node, has one parent.
  • Each node may have any number of children.
  • Nodes with the same parent are siblings.

Because HTML documents often have multiple elements that are of the same type, the DOM allows you to access distinct elements in a node list using an index number. For example, you can refer to the first <p> element in a document as p[0], and the second <p> element node as p[1].

warning Although a node list may look like an array, it’s not. You can loop through the contents of a node list, but you can't use array methods on node lists.

In Listing 10-2, the three <p> elements are all children of the <div> element. Because they have the same parent, they are siblings.

Listing 10-2: Demonstration of Parent, Child, and Sibling Relationships in an HTML Document

<html>
<head>
 <title>The HTML Family</title>
</head>
<body>
 <section> <!-- proud parent of 3 p elements, child of body -->
   <p>First</p> <!-- 1st child of section element, sibling of 2 p elements -->
   <p>Second</p> <!-- 2nd p child of section element, sibling of 2 p elements -->
   <p>Third</p> <!-- 3rd p child of section element, sibling of 2 p elements -->
 </section>
</body> </html>

technicalstuff In Listing 10-2, the HTML comments are also children of the section element. The last comment before the closing section tag is called the last child of the section.

By understanding the relationships between document nodes, you can use the DOM tree to find any element within a document.

Listing 10-3 is an HTML document containing a script that outputs all the child nodes of the section element.

Listing 10-3: Displaying the Child Nodes of the section Element

<html>
<head>
 <title>The HTML Family</title>
</head>
<body>
 <section> <!-- proud parent of 3 p elements, child of body -->
   <p>First</p> <!-- 1st child of section element, sibling of 2 p elements -->
   <p>Second</p> <!-- 2nd p child of section element, sibling of 2 p elements -->
   <p>Third</p> <!-- 3rd p child of section element, sibling of 2 p elements -->
 </section>
 <h1>Nodes in the section element</h1>
 <script>
  var myNodelist = document.body.childNodes[1].childNodes;
  for (i = 0; i < myNodelist.length; i++){
    document.write (myNodelist[i] + "<br>");
  }
 </script>
</body>
</html>

Figure 10-2 shows what the output of Listing 10-3 looks like in a browser. Notice that the first child node of the section element is a text node. If you look closely at the HTML markup in Listing 10-3, you'll see that there is a single space between the opening section tag and the comment. Even something as simple as this single space creates an entire node in the DOM tree. This fact needs to be taken into consideration when you’re navigating the DOM using relationships between nodes.

image

Figure 10-2: Viewing the output of Listing 10-3.

The HTML DOM also provides a couple keywords for navigating nodes using their positions relative to their siblings or parents. The relative properties are

  • firstChild: References the first child of a node
  • lastChild: References the last child of the node
  • nextSibling: References the next node with the same parent node
  • previousSibling: References the previous node with the same parent node

Listing 10-4 shows how you can use these relative properties to traverse the DOM.

Listing 10-4: Using firstChild and lastChild to Highlight Navigation Links

<html>
<head>
 <title>Iguanas Are No Fun</title>
 <script>
  function boldFirstAndLastNav() {
    document.body.childNodes[1].firstChild.style.fontWeight="bold";
    document.body.childNodes[1].lastChild.style.fontWeight="bold";
  }
 </script>

</head>
<body>
 <nav><a href="home.html">Home</a> | <a href="why.html">Why Are Iguanas No Fun?</a> | <a href="what.html">What Can Be Done?</a> | <a href="contact.html">Contact Us</a></nav>
 <p>Iguanas are no fun to be around. Use the links above to learn more.</p>
 <script>
  boldFirstAndLastNav();
 </script>
</body>
</html>

Notice in Listing 10-4 that all the spacing must be removed between the elements within the <nav> element in order for the firstChild and lastChild properties to access the correct elements that we want to select and style.

Figure 10-3 shows what the document in Listing 10-4 looks like when previewed in a browser. Notice that just the first and last links in the navigation are bold.

image

Figure 10-3: Previewing Listing 10-4 in a browser.

This is the first example in which we use the DOM to make a change to existing elements within the document. However, this method of selecting elements is almost never used. It’s too prone to mistakes and too difficult to interpret and use.

In the next section, you see that the DOM provides us with a much better means of traversing and manipulating the DOM than counting its children.

Using the Document Object's Properties and Methods

The Document object provides properties and methods for working with HTML documents. The complete list of Document object properties is shown in Table 10-1. The Document object’s methods are shown in Table 10-2.

Table 10-1 The Document Object's Properties

Property

Use

anchors

Gets a list of all anchors (<a> elements with name attributes) in the document

applets

Gets an ordered list of all the applets in the document

baseURI

Gets the base URI of the document

body

Gets the <body> or <frameset> node of the document body

cookie

Gets or sets the name/value pairs of cookies in the document

doctype

Gets the Document Type Declaration associated with the document

documentElement

Gets the element that is the root of the document (for example, the <html> element of an HTML document)

documentMode

Gets the mode used by the browser to render the document

documentURI

Gets or sets the location of the document

domain

Gets the domain name of the server that loaded the document

embeds

Gets a list of all <embed> elements in the document

forms

Gets a collection of all <form> elements in the document

head

Gets the <head> element in the document

images

Gets a list of all <img> elements in the document

implementation

Gets the DOMImplementation object that handles the document

lastModified

Gets the date and time the current document was last modified

links

Gets a collection of all <area> and <a> elements in the document that contain the href attribute

readyState

Gets the loading status of the document. Returns loading while the document is loading, interactive when it has finished parsing, and complete when it has completed loading

referrer

Gets the URL of the page that the current document was linked from

scripts

Gets a list of <scripts> elements in the document

title

Gets or sets the title of the document

URL

Gets the full URL of the document

Table 10-2 The Document Object's Methods

Method

Use

addEventListener()

Assigns an event handler to the document

adoptNode()

Adopts a node from an external document

close()

Finishes the output writing stream of the document that was previously opened with document.open()

createAttribute()

Creates an attribute node

createComment()

Creates a comment node

createDocumentFragment()

Creates an empty document fragment

createElement()

Creates an element node

createTextNode()

Creates a text node

getElementById()

Gets the element that has the specified ID attribute

getElementByClassName()

Gets all elements with specified class name

getElementByName()

Gets all elements with the specified name

getElementsByTagName()

Gets all elements with the specified tag name

importNode()

Copies and imports a node from an external document

normalize()

Clears the empty text nodes and joins adjacent nodes

open()

Opens a document for writing

querySelector()

Gets the first element that matches the specified group of selector(s) in the document

querySelectorAll()

Gets a list of all the elements that match the specified selector(s) in the document

removeEventListener()

Clears an event handler that had been added using the .addEventListener() method from the document

renameNode()

Renames an existing node

write()

Writes JavaScript code or HTML expressions to a document

writeIn()

Writes JavaScript code or HTML expressions to a document and adds a new line character after each statement

Using the Element Object’s Properties and Methods

The Element object provides properties and methods for working with HTML elements within a document. Table 10-3 shows all the properties of the Element object. Table 10-4 lists all the methods of the Element object.

Table 10-3 The Element Object's properties

Method

Use

accessKey

Gets or sets the accesskey attribute of the element

attributes

Gets a collection of all the element's attribute registered to the specified node (returns a NameNodeMap)

childElementCount

Gets the number of child elements in the specified node

childNodes

Gets a list of the element's child nodes

children

Gets a list of the element's child elements

classList

Gets the class name(s) of the element

className

Gets or sets the value of the class attribute of the element

clientHeight

Gets the inner height of an element, including padding

clientLeft

Gets the left border width of the element

clientTop

Gets the top border width of the element

clientWidth

Gets the width of the element, including padding

contentEditable

Gets or sets whether the element is editable

dir

Gets or sets the value of the dir attribute of the element

firstChild

Gets the first child node of the element

firstElementChild

Gets the first child element of the element

id

Gets or sets the value of the id attribute of the element

innerHTML

Gets or sets the content of the element

isContentEditable

Returns true if the content of an element is editable; returns false if it is not editable

lang

Gets or sets the base language of the elements attribute

lastChild

Gets the last child node of the element

lastElementChild

Gets the last child element of the element

namespaceURI

Gets the namespace URI for the first node in the element

nextSibling

Gets the next node at the same node level

nextElementSibling

Gets the next element at the same node level

nodeName

Gets the current node's name

nodeType

Gets the current node's type

nodeValue

Gets or sets the value of the node

offsetHeight

Gets the height of the element, including vertical padding, borders, and scrollbar

offsetWidth

Gets the width of the element, including horizontal padding, borders, and scrollbar

offsetLeft

Gets the horizontal offset position of the element.

offsetParent

Gets the offset container of the element

offsetTop

Gets the vertical offset position of the element

ownerDocument

Gets the root element (document node) for an element

parentNode

Gets the parent node of the element

parentElement

Gets the parent element node of the element

previousSibling

Gets the previous node at the same node tree level

previousElementSibling

Gets the previous element node at the same node tree level

scrollHeight

Gets the entire height of the element, including padding

scrollLeft

Gets or sets the number of pixels the element's content is scrolled horizontally

scrollTop

Gets or sets the number of pixels the element's content is scrolled vertically

scrollWidth

Gets the entire width of the element, including padding

style

Gets or sets the value of the style attribute of the element

tabIndex

Gets or sets the value of the tabindex attribute of the element

tagName

Gets the tag name of the element

textContent

Gets or sets the textual content of the node and its descendants

title

Gets or sets the value of the title attribute of the element

length

Gets the number of nodes in the NodeList

Table 10-4 The Element Object’s Methods

Method

Use

addEventLIstener()

Registers an event handler to the element

appendChild()

Inserts a new child node to the element (as a last child node)

blur()

Eliminates focus from the element

click()

Replicates a mouse-click on the element

cloneNode()

Clones the element

compareDocumentPosition()

Compares the document position of two elements

contains()

Yields true if the node is a descendant of a node; otherwise, yields false

focus()

Gives focus to the element

getAttribute()

Gets the specified attribute value of the element node

getAttributeNode()

Gets the specified attribute node

getElementsByClassName()

Gets a collection of all child elements with the stated class name.

getElementByTagName()

Gets a collection of all the child elements with the stated tag name

getFeature()

Gets an object that implements the API's of the stated feature

hasAttribute()

Yields true if the element has the stated attribute; otherwise, yields false

hasAttributes()

Yields true if the element has any attributes; otherwise, yields false

hasChildNodes()

Yields true if the element has any child nodes; otherwise, yields false

insertBefore()

Enters a new child node before the stated existing node

isDefaultNamespace()

Yields true if the stated namespaceURI is the default; otherwise, yields false

isEqualNode()

Evaluates to see whether two elements are equal

isSameNode()

Evaluates to see whether two elements are the same node

isSupported()

Yields true if the stated feature is supported on the element

normalize()

Joins the specified nodes with their adjacent nodes and removes any empty text nodes

querySelector()

Gets the first child element that matches the stated CSS selector(s) of the element

querySelectorAll()

Gets all the child elements that match the stated CSS selector(s) of the element

removeAttribute()

Takes the stated attribute out of the element

removeAttributeNode()

Takes the stated attribute node out of the element and retrieves the removed node

removeChild()

Removes the stated child node

replaceChild()

Replaces specified child node with another

removeEventListener()

Removes the specified event handler

setAttribute()

Changes or sets the stated attribute to the specified value

setAttributeNode()

Changes or sets the stated attribute node

toString()

Changes an element to a string

item()

Get the node at the stated index in the NodeList

Working with the Contents of Elements

You can display node types and node values by using the HTML DOM. You also can set property values of elements within the DOM using the Element object. When you use JavaScript to set the properties of DOM elements, the new values are reflected in real-time within the HTML document.

Changing the properties of elements in a web document in order to reflect them instantly in the browser, without needing to refresh or reload the web page, is a cornerstone of what used to be called Web 2.0.

innerHTML

The most important property of an element that you can modify through the DOM is the innerHTML property.

The innerHTML property of an element contains everything between the beginning and ending tag of the element. For example, in the following code, the innerHTML property of the div element contains a p element and its text node child:

<body><div><p>This is some text.</p></div></body>

technicalstuff It’s very common in web programming to create empty div elements in your HTML document and then use the innerHTML property to dynamically insert HTML into the elements.

To retrieve and display the value of the innerHTML property, you can use the following code:

var getTheInner = document.body.firstChild.innerHTML;
document.write (getTheInner);

In the preceding code, the value that will be output by the document.write() method is

<p>This is some text.</p>

Setting the innerHTML property is done in the same way that you set the property of any object:

document.body.firstChild.innerHTML = "Hi there!";

The result of running the preceding JavaScript will be that the p element and the sentence of text in the original markup will be replaced with the words "Hi There!" The original HTML document remains unchanged, but the DOM representation and the rendering of the web page will be updated to reflect the new value. Because the DOM representation of the HTML document is what the browser displays, the display of your web page will also be updated.

Setting attributes

To set the value of an HTML attribute, you can use the setAttribute() method:

document.body.firstChild.innerHTML.setAttribute("class", "myclass");

The result of running this statement is that the first child element of the body element will be given a new attribute named "class" with a value of "myclass".

Getting Elements by ID, Tag Name, or Class

The getElementBy methods provide easy access to any element or groups of elements in a document without relying on parent/child relationships of nodes. The three most commonly used ways to access elements are

  • getElementById
  • getElementsByTagName
  • getElementsByClassName

getElementById

By far the most widely used method for selecting elements, getElementById is essential to modern web development. With this handy little tool, you can find and work with any element simply by referencing a unique id attribute. No matter what else happens in the HTML document, getElementById will always be there for you and will reliably select the exact element that you want.

Listing 10-5 demonstrates the awesome power of getElementById to enable you to keep all your JavaScript together in your document or to modularize your code. By using getElementById, you can work with any element, anywhere in your document just as long as you know its id.

Listing 10-5: Using getElementById to Select Elements

<html>
<head>
 <title>Using getElementById</title>
 <script>
  function calculateMPG(miles,gallons){
   document.getElementById("displayMiles").innerHTML = parseInt(miles);
   document.getElementById("displayGallons").innerHTML = parseInt(gallons);
   document.getElementById("displayMPG").innerHTML = miles/gallons;
  }
 </script>
</head>
<body>
  <p>You drove <span id="displayMiles">___</span> miles.</p>
  <p>You used <span id="displayGallons">___</span> gallons of gas.</p>
  <p>Your MPG is <span id="displayMPG">___</span>.
  <script>
    var milesDriven = prompt("Enter miles driven");
    var gallonsGas = prompt("Enter the gallons of gas used");
    calculateMPG(milesDriven,gallonsGas);
 </script>
</body>
</html>

getElementsByTagName

The getElementsByTagName method returns a node list of all the elements with the specified tag name. For example, in Listing 10-6, getElementsByTagName is used to select all h1 elements and change their innerHTML properties to sequential numbers.

Listing 10-6: Using getElementsByTagName to Select and Change Elements

<html>
<head>
 <title>Using getElementsByTagName</title>
 <script>
  function numberElements(tagName){
   var getTags = document.getElementsByTagName(tagName);
   for(i=0; i < getTags.length; i++){
     getTags[i].innerHTML = i+1;
   }
  }
 </script>
</head>
<body>
  <h1>this text will go away</h1>
  <h1>this will get overwritten</h1>
  <h1>JavaScript will erase this</h1>
  <script>
     numberElements("h1");
  </script>
</body>
</html>

getElementsByClassName

The getElementsByClassName method works in much the same way as the getElementsByTagName, but it uses the values of the class attribute to select elements. The function in Listing 10-7 selects elements with a class of "error" and will change the value of their innerHTML property.

Listing 10-7: Using getElementsByClassName to Select and Change Elements

<html>
<head>
 <title>Using getElementsByClassName</title>
 <script>
   function checkMath(result){
    var userMath = document.getElementById("answer1").value;
    var errors = document.getElementsByClassName("error");
    if(parseInt(userMath) != parseInt(result)) {
      errors[0].innerHTML = "That's wrong. You entered " + userMath + ". The answer is " + result;
    } else {
      errors[0].innerHTML = "Correct!";
    }
   }
 </script>
</head>
<body>
   <label for = "number1">4+1 = </label><input type="text" id="answer1" value="">
   <button id="submit" onclick="checkMath(4+1);">Check your math!</button>
   <h1 class="error"></h1>
</body>
</html>

The result of running Listing 10-7 in a web browser and entering a wrong answer is shown in Figure 10-4.

image

Figure 10-4: Using the getElementsByClassName to select an element for displaying an error message.

technicalstuff Notice that Listing 10-7 uses an onclick attribute inside the button element. This is an example of a DOM event handler attribute. You can find out more about event handlers in Chapter 11.

Using the Attribute Object’s Properties

The Attribute object provides properties for working with attributes within the HTML elements. Table 10-5 lists all the Attribute object’s properties.

Table 10-5 The Attribute Object’s Properties

Property

Use

isId

Yields true if the attribute is an Id; otherwise, yields false

name

Gets the name of the attribute

value

Gets or sets the value of the attribute

specified

Yields true if the attribute has been specified; otherwise, yields false

Creating and appending elements

To create a new element in an HTML document, use the document.createElement() method. When you use createElement(), a new beginning and end tag of the type you specify will be created.

Listing 10-8 shows an example of how you can use this method to dynamically create a list in an HTML document from an array.

Listing 10-8: Using document.createElement() to Generate a Table from an Array

<html>
<head>
 <title>Generating a list</title>
</head>
<body>
 <h1>Here are some types of balls</h1>
 <ul id="ballList">
 </ul>

 <script>
   var typeOfBall = ["basket", "base", "soccer", "foot", "hand"];
   for (i=0; i<typeOfBall.length; i++) {
     var listElement = document.createElement("li");
     listElement.innerHTML = typeOfBall[i];
      document.getElementById("ballList").appendChild(listElement);
     }
 </script>
</body>
</html>

Removing elements

For all the great things that it lets you do with HTML documents, the HTML DOM is not highly regarded by professional JavaScript programmers. It has a number of oddities and tends to make some things more difficult than they should be.

One of the big faults with the DOM is that it doesn’t provide any way to directly remove an element from a document. Instead, you have to tell the DOM to find the parent of the element you want to remove and then tell the parent to remove its child. It sounds a little confusing, but Listing 10-9 should clear it all up.

Listing 10-9: Removing an Element from a Document

<html>
<head>
 <title>Remove an element</title>
 <script>
  function removeFirstParagraph(){
    var firstPara = document.getElementById("firstparagraph");
    firstPara.parentNode.removeChild(firstPara);
  }
 </script>
</head>
<body>
 <div id="gibberish">
  <p id="firstparagraph">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum molestie pulvinar ante, a volutpat est sodales et. Ut gravida justo ac leo euismod, et tempus magna posuere. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer non mi iaculis, facilisis risus et, vestibulum lorem. Sed quam ex, placerat nec tristique id, mattis fringilla ligula. Maecenas a pretium justo. Suspendisse sit amet nibh consectetur, tristique tellus quis, congue arcu. Etiam pellentesque dictum elit eget semper. Phasellus orci neque, semper ac tortor ac, laoreet ultricies enim.</p>
 </div>
 <button onclick="removeFirstParagraph();">That's Gibberish!</button>
</body>
</html>

When you run Listing 10-9 in a browser and press the button, the onclick event calls the removeFirstParagraph() function.

The first thing removeFirstParagraph() does is to select the element that we actually want to remove, the element with the id = "firstparagraph". Then, the script selects the parent node of the first paragraph. It then uses the removeChild() method to remove the first paragraph.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset