JS DOM Navigation

Navigating Between DOM Nodes

In the previous sections, you've learned how to select individual elements on a webpage. However, there are times when you need to access child, parent, or ancestor elements. Refer to the JavaScript DOM nodes chapter to understand the logical relationships among nodes in a DOM tree.

DOM nodes offer various properties and methods that help you navigate through the DOM tree structure and make changes effortlessly. In the upcoming section, we'll explore how to move up, down, and sideways within the DOM tree using JavaScript.

Accessing the Child Nodes

You can utilize the firstChild and lastChild properties of a DOM node to retrieve its first and last direct child nodes, respectively. If the node has no child elements, these properties return null.

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>

<script>
var main = document.getElementById("main");
console.log(main.firstChild.nodeName); // Prints: #text

var hint = document.getElementById("hint");
console.log(hint.firstChild.nodeName); // Prints: SPAN
</script>

Note: The nodeName property is read-only and provides the name of the current node as a string. For instance, it returns the tag name for an element node, #text for a text node, #comment for a comment node, #document for a document node, and so forth.

If you observe the example above, the nodeName of the first child node within the main <div> element returns #text instead of H1. This occurs because whitespace such as spaces, tabs, and newlines are considered valid characters and form #text nodes within the DOM tree. Therefore, since the <div> tag includes a newline before the <h1> tag, it creates a #text node.

To address the issue of firstChild and lastChild returning #text or #comment nodes, you can instead use the firstElementChild and lastElementChild properties. These properties retrieve only the first and last element nodes, respectively. However, please note that these properties are not supported in IE 9 and earlier versions.

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>

<script>
var main = document.getElementById("main");
alert(main.firstElementChild.nodeName); // Outputs: H1
main.firstElementChild.style.color = "red";

var hint = document.getElementById("hint");
alert(hint.firstElementChild.nodeName); // Outputs: SPAN
hint.firstElementChild.style.color = "blue";
</script>

Likewise, you can utilize the childNodes property to retrieve all child nodes of a specific element, with the first child node indexed at 0. Here is an example:

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>

<script>
var main = document.getElementById("main");

// First check that the element has child nodes 
if(main.hasChildNodes()) {
var nodes = main.childNodes;

// Loop through node list and display node name
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>

The childNodes property retrieves all child nodes of an element, including non-element nodes such as text and comment nodes. If you specifically want a collection containing only elements, you should use the children property instead.

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>

<script>
var main = document.getElementById("main");

// First check that the element has child nodes 
if(main.hasChildNodes()) {
var nodes = main.children;

// Loop through node list and display node name
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>

Accessing the Parent Nodes

To retrieve the parent of a particular node within the DOM tree, you can utilize the parentNode property.

For a document node, the parentNode property always returns null, as it does not have a parent.

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>

<script>
var hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Outputs: DIV
alert(document.documentElement.parentNode.nodeName); // Outputs: #document
alert(document.parentNode); // Outputs: null
</script>

 

Tip: The topmost nodes of the DOM tree can be directly accessed as properties of the document object. For instance, the <html> element is accessible via document.documentElement, the <head> element via document.head, and the <body> element via document.body.

However, if you want to get only element nodes you can use the parentElement, like this:

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>

<script>
var hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Outputs: DIV
hint.parentNode.style.backgroundColor = "yellow";
</script>

Accessing the Sibling Nodes

To access the previous and next nodes in the DOM tree, you can use the previousSibling and nextSibling properties. Here is an example:

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p><hr>
</div>

<script>
var title = document.getElementById("title");
alert(title.previousSibling.nodeName); // Outputs: #text

var hint = document.getElementById("hint");
alert(hint.nextSibling.nodeName); // Outputs: HR
</script>

Alternatively, you can utilize the previousElementSibling and nextElementSibling properties to retrieve the previous and next sibling elements, skipping any whitespace text nodes. Each of these properties returns null if there is no such sibling element. Here's an example:

<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>

<script>
var hint = document.getElementById("hint");
alert(hint.previousElementSibling.nodeName); // Outputs: H1
alert(hint.previousElementSibling.textContent); // Outputs: My Heading

var title = document.getElementById("title");
alert(title.nextElementSibling.nodeName); // Outputs: P
alert(title.nextElementSibling.textContent); // Outputs: This is some text.
</script>

The textContent property represents the combined text content of a node and all its descendants. Refer to the JavaScript DOM manipulation chapter for more details.


Types of DOM Nodes

The DOM tree consists of various types of nodes, including elements, text, comments, and others.

Each node possesses a nodeType property that identifies its type. The table below outlines the key node types:

Constant Value Description
ELEMENT_NODE 1 An element node, such as <p> or <img>.
TEXT_NODE 3 The actual textual content within an element.
COMMENT_NODE 8 A comment node, for example, <!-- some comment -->.
DOCUMENT_NODE 9 A document node, representing the parent of the <html> element.
DOCUMENT_TYPE_NODE 10 A document type node, such as <!DOCTYPE html> for HTML5 documents.