Bookmark and Share

Introduction to the Document Object Model

Review the W3C DOM2 standard recommendation.

The first step is to create a node object of the type you want using one of document.createElement(), document.createAttribute() or document.createTextNode(). For attributes, however, you'll probably just want to create an element node and assign it attributes directly (recall that IE, as of version 5.5, doesn't support createAttribute()).

Working with Text Nodes

Let's start with a text node. Below is some sample code showing how to create a text node and assign it a value.

var myTextNode = document.createTextNode("my text");

Now you have a text node. But it's not part of the document tree. To make it appear on the page, you need to add it as a child to an existing node within the tree. Since text nodes cannot have children, you can't attach it to another text node. Attributes nodes are not part of the document tree, so you don't want to attach it to one of them. That leaves element nodes.

Since element nodes can several children, there are a few different methods provided that allow you to specify where to add the new node among its existing children. These are best illustrated by example.

Here, the appendChild() method is used to add new text to a paragraph element. It also allows you to remove the last node added using the removeChild() method:

Initial text within a paragraph element.

Add Text Node | Remove Text Node

Now take a look at the code:

<p id="sample1">Initial text within a paragraph element.</p>

... code to add a text node ...

var text = document.createTextNode(" new text " + (++counter1));
var el = document.getElementById("sample1");

... code to remove the last child node ...

var el = document.getElementById("sample1");
if (el.hasChildNodes())

Adding text is easy, the code creates a new text node, locates the paragraph element node and calls appendChild() to insert it at the end of it's childNodes array. A global counter variable is used on the text itself so you can distinguish each new node in the browser display.

Removing text is almost as easy, using a call to removeChildNode(). The only difference in the addition of a reference node, to indicate which of the element's children is to be removed. Here we use the element's lastChild property which always points to the last node of the element's childNodes array. Note that it will even remove the initial text hard coded in the P tag if that is the only child.

Also note the use of the hasChildNodes() method which simply returns true or false to indicate if the given node currently has any children. Here it's used to prevent an error by calling removeChild when there are no children left.

Normalizing and Splitting Text Nodes

In the above example, the new text nodes are added as independent children. But if you had hard coded additional text in the HTML,

<p id="sample1">Initial text within a paragraph element. new text 1
new text 2 new text 3</p>

it would appear in the DOM as a single child text node of the paragraph element. In other words, the node tree produced by dynamically adding content may appear different from the node tree that would result if that content had been included in the static HTML code.

This may or may not be desirable depending on what you're trying to do. In some cases you may want combine text nodes to make the tree reflect what it would if the new, dynamically added content had been part of the original, static HTML code.

The normalize() method provides this functionality. Calling it on an element will "clean up" the node tree, combining any adjacent text nodes and removing any empty ones.

Browser Compatibility

Internet Explorer 5.5 does not support the normalize method. The example below will not work properly on this browser. IE 6.0, however, does appear to support it although the current beta version is buggy.

To demonstrate, here's the same example used above but with additional links provided to normalize the paragraph element and show it's current number of children.

Initial text within a paragraph element.

Add Text Node | Remove Text Node | Show Child Node Count | Normalize Element

You can see that as you add text, the number of child nodes increases but any time you normalize the paragraph, they are combined into a single text node. Here's the code for the additional links:

... normalize element ...

el = document.getElementById("sample2");

... show number of child nodes ...

el = document.getElementById("sample2");

Conversely, you can split a single text node into two separate ones using the splitText() method This can be useful if you want to dynamically alter a single word or phrase or insert an element in a line of text.

Let's set up another example. This time, the remove link will delete the first child of the paragraph. Initially, this will be the entire sentence. But if you use the separate link first, it will split off the first word in the text and a subsequent remove will delete only that word. The reset link allows you to start over.

Initial text within a paragraph element.

Separate First Word | Remove First Text Node | Reset

And here's the code for each function:

... split at first word ...

el = document.getElementById("sample3");
if (el.hasChildNodes()) {
  text = el.firstChild;
  i = text.nodeValue.indexOf(" ");
  if (i >= 0)
    text.splitText(i + 1);

... remove first text node ...

el = document.getElementById("sample3");
if (el.hasChildNodes())

... reset the example ...

el = document.getElementById("sample3");
while (el.hasChildNodes())
text = document.createTextNode(
  "Initial text within a paragraph element.");

A couple of notes here. The nodeValue of a text node is simply a string. The splitText() method expects an offset value to tell it where to split the text. The string indexOf() method is used to find the offset of the first space in the text and pass it on to splitText().

Second, the reset code simply deletes all child nodes of the paragraph and then adds the original text back as a single node.