Traversing the DOM
A DOM node contains a selection of properties that will let us move from one node to another. Each node has a parentNode
property that returns the parent of the node. Each node also has a childNodes
property that returns an array like NodeList
containing all the children of the node. These properties are essentially links between nodes, formed by the parent, child and sibling relationships of nodes. Here is a list of useful properties.
Property | Definition |
---|---|
parentNode | Returns a Node that is the parent of this node. If there is no such node, this property returns null. |
childNodes | Returns an array like NodeList of all children of this node. |
firstChild | Returns the first direct child of this node. |
lastChild | Returns the last direct child of this node. |
nextSibling | Returns the next node in the tree. |
previousSibling | Returns the previous node in the tree. |
Let us explain the relationships between DOM nodes in an easy to understand fashion through the use of a simple example.
<!doctype html>
<html>
<head>
<title>My title</title>
</head>
<body>
<h1>A heading</h1>
<a href="www.altcademy.com">Link text</a>
<p>Hello World!</p>
</body>
</html>
Lets focus on the body element and the elements inside body. Their relationships can be summarized as below.
document.body.childNodes
contains all three elementsh1
,a
andp
.- You can access the childNodes by bracket notation. Index 0 represents
h1
, 1 representsa
and 2 representsp
. - The
firstChild
ofbody
is theh1
element. - The
lastChild
ofbody
is thep
element. - The
nextSibling
ofh1
isa
. - The
previousSibling
ofp
isa
. - All three childNodes'
paretNode
is thebody
element.
Note that if a node does not contain any children, its firstChild
and lastChild
properties return null and its childNodes
property will be an empty NodeList
. firstChild
's previousSibling
will return null
and lastChild
's nextSibling
will return null
.
We can now easily traverse the DOM tree using those relationship properties. As an example, we can write a recursive function to print out all the text content of text nodes in the body
element. We will pretend we don't know what the content consists of and how many nodes and nested nodes there are. The best way to implement this is to write a recursive function.
var printContent = function (node) {
if (node.hasChildNodes()) {
for (var i = 0; i < node.childNodes.length; i++) {
printContent(node.childNodes[i]);
}
} else if (node.nodeType == document.TEXT_NODE) {
if (node.nodeValue.trim()) {
console.log(node.nodeValue);
}
}
}
printContent(document.body);
// -> A heading
// -> Link text
// -> Hello World!
Try it out yourself on Repl.it.
The method hasChildNodes
returns true if the node has child nodes, otherwise it returns false. The nodeValue
property will return the content of the node, it also lets you set the content as well. For a text node, the nodeValue
property returns / sets the text content. We use the trim method to get rid of the new line white space character text nodes in between our elements so that we will only console log the text belonging to our elements.