JS DOM Navigation

Welcome to another tutorial, here you will learn how to navigate between DOM nodes in JavaScript.
 

Navigating Between DOM Nodes

In the previous tutorial, you learned how to select individual elements on a web page. However, in most cases, you might need to access a child, parent, or ancestor element. You can refer back to the JavaScript DOM nodes tutorial to better understand the logical relationships between the nodes in a DOM tree.

The Document Object Model (DOM) node provides many properties and various methods that allow you to navigate or traverse through the tree structure of the DOM and allows changes very easily.

In later sections in this tutorial, you will learn how to navigate up, down, and sideways in the DOM tree using JavaScript.

 

Accessing the Child Nodes

To access the first and last direct child node of a node, you will need to use the firstChild and lastChild properties respectively. However, if the node doesn't have any child element, it returns null.

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

<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>

Try with example

From the example above, the nodeName of the first child node of the main DIV element returns #text instead of H1. This is because, whitespace such as spaces, tabs, newlines, etc., are valid characters and therefore, form #text nodes and become part of the DOM tree. 

Since the <div> tag contains a newline before the <h1> tag, it will create a #text node.

In other to prevent the firstChild and lastChild from returning #text or #comment nodes, you could alternatively use the firstElementChild and lastElementChild properties to return only the first and last element node, respectively. However, it will not work in Internet Explorer (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>

Try with example

Meanwhile, you can use the childNodes property to access all child nodes of a given element, if the first child node is assigned index 0. This 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>

Try with example

 

All child nodes are returned by the childNodes property, including non-element nodes like text and comment nodes. You can use children property to get a collection of only elements.

<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>

Try with example

 

Accessing the Parent Nodes

In this case, the parentNode property can be used to access the parent of the specified node in the DOM tree.

The parentNode will at all-time return null for the document node, because it doesn't 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>

Try with example

 

Tip: The topmost DOM tree nodes can only be accessed directly as document properties. For instance this, the <html> element can be accessed with ‘document.documentElement’ property, while the <head> element can be accessed with ‘document.head’ property, and also, the <body> element can be accessed with ‘document.body’ property.

The parentElement is used when you want to get only element nodes, like in the example below:

<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>

Try with example


Accessing the Sibling Nodes

In this case, the previousSibling and nextSibling properties are used to access the previous and next node in the DOM tree, respectively. Below 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>

Try with example

 

Alternatively, the previousElementSibling and nextElementSibling can be used to get the previous and next sibling element, while skipping any whitespace text nodes. However, all these properties return null if there is no such sibling. This is illustrated in this 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>

Try with example

Note: The textContent property represents the text content of a node and its descendants. You can check out the JavaScript DOM manipulation tutorial to learn more about it.

 

Types of DOM Nodes

The DOM tree is made up of different types of nodes, such as elements, text, comments, etc.

All node has a nodeType property that can be used to find out what type of node you are dealing with. The table below lists the most important node types:

ConstantValueDescription
ELEMENT_NODE1An element node such as <p> or <img>.
TEXT_NODE3The actual text of element.
COMMENT_NODE8A comment node i.e. <!-- some comment -->
DOCUMENT_NODE9A document node i.e. the parent of <html> element.
DOCUMENT_TYPE_NODE10A document type node e.g. <!DOCTYPE html> for HTML5 documents.