|
|
|
|
WEB DEVELOPER TIPS: TRAVERSING
& PRINTING
THE DOM TREE OF A HTML ELEMENT
|
|
|
Background
|
|
|
This tutorial contains an example of traversing a DOM element. It assumes a fairly good understanding of data structures, and also a fair background in JavaScript.What is DOM?
DOM stands for Document Object Model. It is
an interface that represent the
content of a document. Think of an interface as a structural
description of a piece of data. The official DOM specification is available in www.w3.org.
In DOM, the
data is an html document, and the data structure is a "tree." The
purpose of DOM is to specify an universally accepted
interface, so that languages such as JavaScript can access and
manipulate the content of a DOM (ie: the content of an an html
page) in a consistent manner. Within a html page, the DOM tree contains elements such as <HEAD>, <TABLE>, <IMG>, and so on.
For example: in this html page below, the DOM will look like the
following: click
this link to see the DOM tree.
|
|
| |
|
Please note that the browser must support DOM and JavaScript must be enabled to run the example. (The
examples were tested on Firefox 1.02, Internet Explorer 6.2,
Netscape 7, Netscape 8 on Windows XP). The tree opens on a
new window. Popup blockers might prevent the window from
showing. On browsers with
tabbed Windows (Netscape 8 for example), the tree might be printed
on a Tabbed window.
<HTML>
<HEAD>
<TITLE>Html Title
</TITLE>
</HEAD>
<BODY>
<DIV>
<TABLE>
<TR>
<TD>Table cell 1
</TD>
</TR>
<TR>
<TD>Table cell 2
</TD>
</TR>
</TABLE>
</DIV>
</BODY>
</HTML>
|
This is how the tree looks like in two different
browsers. There are slight differences between browsers, as
you can see. While you should be aware of this fact, the
elements in the html code (such are the TABLE, TR,
and TD, above) are present in both. And most
importantly, the structure of both trees are virtually
identical.
Internet
Explorer 6 |
Firefox
1.02 |
<HTML>
¦
¦--<HEAD>
¦ ¦
¦ ¦--<TITLE>
¦ ¦ </TITLE>
¦ </HEAD>
¦
¦--<BODY>
¦ ¦
¦ ¦--<TABLE>
¦ ¦ ¦
¦ ¦ ¦--<TBODY>
¦ ¦ ¦ ¦
¦ ¦ ¦ ¦--<TR>
¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦--<TD>
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦ ¦--[unknown
tag]
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦
</TD>
¦ ¦ ¦ ¦
</TR>
¦ ¦ ¦ ¦
¦ ¦ ¦ ¦--<TR>
¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦--<TD>
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦ ¦--[unknown
tag]
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦
</TD>
¦ ¦ ¦ ¦
</TR>
¦ ¦ ¦ </TBODY>
¦ ¦ </TABLE>
¦ </BODY>
</HTML> |
<HTML>
¦
¦--<HEAD>
¦ ¦
¦ ¦--<TITLE>
¦ ¦ ¦
¦ ¦ ¦--[unknown tag]
¦ ¦ ¦
¦ ¦ </TITLE>
¦ </HEAD>
¦
¦--[unknown tag]
¦
¦
¦--<BODY>
¦ ¦
¦ ¦--<TABLE>
¦ ¦ ¦
¦ ¦ ¦--<TBODY>
¦ ¦ ¦ ¦
¦ ¦ ¦ ¦--<TR>
¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦--<TD>
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦ ¦--[unknown tag]
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦ </TD>
¦ ¦ ¦ ¦ </TR>
¦ ¦ ¦ ¦
¦ ¦ ¦ ¦--<TR>
¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦--<TD>
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦ ¦--[unknown tag]
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ ¦ ¦ ¦ </TD>
¦ ¦ ¦ ¦ </TR>
¦ ¦ ¦ </TBODY>
¦ ¦ </TABLE>
¦ ¦
¦ ¦--[unknown tag]
¦ ¦
¦ </BODY>
</HTML>
|
In the DOM terminology, an element is referred as a node.
A node always has a parentNode (unless it's the root node);
and a node can have one or more childNodes. In the
above example, let's examine the <HEAD> node.
The parentNode of that <HEAD> node is the <HTML>
node; and the firstChild or the childNodes[0] of that <HEAD> node
is the <TITLE> node.
The <HTML> node in the above example does not have a parentNode;
such node is referred as the root node.
A node may have siblings, which can be retrieved by using prevSibling
(prev stands for previous) and nextSibling. The <TITLE> node, for
example, does not have any sibling. The two <TR>
nodes however; are siblings of each other.
Siblings do not have to be of the same type. For instance, the <HEAD>
node and the <BODY> nodes are siblings. (In
the tree shown above, when 2 nodes are indented on the same
level, they're siblings of each other.)
Notice something here: In the Internet Explorer tree, the prevSibling
of the <BODY> node is the <HEAD>
node. However, in the Firefox tree, there's an [unknown]
node between the <HEAD> and the <BODY>
node. Thus, when coding, it's sometimes important to do more
checking (such as checking for nodeType or nodeName)
before making any assumption about the identity of any particular
node.
Here are some more important properties of a node.
This list is not exhaustive.
parentNode
|
the parent node of the current node
|
childNodes[n]
|
retrieves the n-th child of the current node
|
firstChild
|
the first child of the current node, or nothing if
there's none
|
lastChild
|
the last child of the current node, or nothing if
there's none
|
nextSibling
|
the next sibling of the current node, or nothing if there's
none
|
prevSibling
|
the previous sibling of the current node, or nothing if
there's none
|
nodeType
|
the node type, such as "TR", "IMG",
"TABLE", etc.
|
attributes
|
the node's attribute objects
|
nodeName
|
the name of the node
|
|
|
|
JavaScript Code to
Print the DOM Tree
|
|
|
Below is an example code that traverses the DOM tree of an html
element. There
are two functions:
- The function traverseDOMTree is called recursively to traverse
an element (a node) until there's no more branch to traverse.
- The function printDOMTree
accepts an element (a node) and prints out the element's DOM tree.
This function basically opens a new browser window to print
output. It is not as important as traverseDOMTree (the
bulk of the concept is in traverseDOMTree).
The important parts and explanations are marked in blue.
<SCRIPT LANGUAGE="JavaScript">
<!--
// F. Permadi 2005.
// (C) F. Permadi
// Print DOM tree
////////////////////////////////////////////
// This function traverses the DOM tree of an element and prints the tree.
// This function called recursively until the DOM tree is fully traversed.
//
// Parameters:
// - targetDocument is where the tree will be printed into
// - currentElement is the element that we want to print
// - depth is the depth of the current element
// (it should be 1 for the initial element)
////////////////////////////////////////////
function traverseDOMTree(targetDocument, currentElement, depth)
{
if (currentElement)
{
var j;
var tagName=currentElement.tagName;
// Prints the node tagName, such as <A>, <IMG>, etc
if (tagName)
targetDocument.writeln("<"+currentElement.tagName+">");
else
targetDocument.writeln("[unknown tag]");
// Traverse the tree
var i=0;
var currentElementChild=currentElement.childNodes[i];
while (currentElementChild)
{
// Formatting code (indent the tree so it looks nice on the screen)
targetDocument.write("<BR>\n");
for (j=0; j<depth; j++)
{
// ¦ is just a vertical line
targetDocument.write(" ¦");
}
targetDocument.writeln("<BR>");
for (j=0; j<depth; j++)
{
targetDocument.write(" ¦");
}
if (tagName)
targetDocument.write("--");
// Recursively traverse the tree structure of the child node
traverseDOMTree(targetDocument, currentElementChild, depth+1);
i++;
currentElementChild=currentElement.childNodes[i];
}
// The remaining code is mostly for formatting the tree
targetDocument.writeln("<BR>");
for (j=0; j<depth-1; j++)
{
targetDocument.write(" ¦");
}
targetDocument.writeln(" ");
if (tagName)
targetDocument.writeln("</"+tagName+">");
}
}
////////////////////////////////////////////
// This function accepts a DOM element as parameter and prints
// out the DOM tree structure of the element.
////////////////////////////////////////////
function printDOMTree(domElement, destinationWindow)
{
// Use destination window to print the tree. If destinationWIndow is
// not specified, create a new window and print the tree into that window
var outputWindow=destinationWindow;
if (!outputWindow)
outputWindow=window.open();
// make a valid html page
outputWindow.document.open("text/html", "replace");
outputWindow.document.write("<HTML><HEAD><TITLE>DOM</TITLE></HEAD><BODY>\n");
outputWindow.document.write("<CODE>\n");
traverseDOMTree(outputWindow.document, domElement, 1);
outputWindow.document.write("</CODE>\n");
outputWindow.document.write("</BODY></HTML>\n");
// Here we must close the document object, otherwise Mozilla browsers
// might keep showing "loading in progress" state.
outputWindow.document.close();
}
//-->
</SCRIPT>
|
Please retain the copyright notice and provide a link back to
this site if you use the script.
To use the script, let's see an example. If I have this section on my html page:
<DIV ID="myDiv">
<TABLE ID="myTable">
<TR><TD>Table content</TD>
<TD>More content</TD>
</TR>
</TABLE>
</DIV>
|
I can print the DOM tree of that DIV node by calling:
printDOMTree(document.getElementById('myDiv'));
|
I can also print the DOM tree of the TABLE node by
calling:
printDOMTree(document.getElementById('myTable'));
|
(Note: the DIV ID is case sensitive in Mozilla
browsers; so when calling getElementById(idOfElement), the
idOfElement parameter letter
casing must match
the way it's declared. For example, if you have a <TABLE
ID="myTable">, the id must be typed as 'myTable'; not
'mytable', and not 'MyTable'.)
Conceptual example: DOM
Tree Test Page.
Real world example: Highlighting
Table Rows (see Option 2).
|
|
|
|
|
|
|
|
|
|
|
|
(C) F. Permadi
permadi@permadi.com
<<INDEX>>
Terms
of Use
|
|
|