JavaScript DOM Navigation
In this tutorial you will learn how to navigate between DOM nodes in JavaScript.
Navigating Between DOM Nodes
In the previous chapters you've learnt how to select individual elements on a web page. But there are many occasions where you need to access a child, parent or ancestor element. See the JavaScript DOM nodes chapter to understand the logical relationships between the nodes in a DOM tree.
DOM node provides several properties and methods that allow you to navigate or traverse through the tree structure of the DOM and make changes very easily. In the following section we will learn how to navigate up, down, and sideways in the DOM tree using JavaScript.
Accessing the Child Nodes
You can use the firstChild
and lastChild
properties of the DOM node to access the first and last direct child node of a node, respectively. If the node doesn't have any child element, it returns null
.
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
let main = document.getElementById("main");
console.log(main.firstChild.nodeName); // Prints: #text
let hint = document.getElementById("hint");
console.log(hint.firstChild.nodeName); // Prints: SPAN
</script>
Note: The nodeName
is a read-only property that returns the name of the current node as a string. For example, it returns the tag name for element node, #text
for text node, #comment
for comment node, #document
for document node, and so on.
If you notice the above example, the nodeName
of the first-child node of the main DIV element returns #text instead of H1. Because, whitespace such as spaces, tabs, newlines, etc. are valid characters and they form #text nodes and become a part of the DOM tree. Therefore, since the <div>
tag contains a newline before the <h1>
tag, so it will create a #text node.
To avoid the issue with firstChild
and
returning #text or #comment nodes, you could alternatively use the lastChild
firstElementChild
and lastElementChild
properties to return only the first and last element node, respectively. But, it will not work in IE 9 and earlier.
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
let main = document.getElementById("main");
alert(main.firstElementChild.nodeName); // Outputs: H1
main.firstElementChild.style.color = "red";
let hint = document.getElementById("hint");
alert(hint.firstElementChild.nodeName); // Outputs: SPAN
hint.firstElementChild.style.color = "blue";
</script>
Similarly, you can use the childNodes
property to access all child nodes of a given element, where the first child node is assigned index 0. Here's an example:
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
let main = document.getElementById("main");
// First check that the element has child nodes
if(main.hasChildNodes()) {
let nodes = main.childNodes;
// Loop through node list and display node name
for(let i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
The childNodes
returns all child nodes, including non-element nodes like text and comment nodes. To get a collection of only elements, use children
property instead.
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
let main = document.getElementById("main");
// First check that the element has child nodes
if(main.hasChildNodes()) {
let nodes = main.children;
// Loop through node list and display node name
for(let i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
Accessing the Parent Nodes
You can use the parentNode
property to access the parent of the specified node in the DOM tree.
The parentNode
will always return null
for document node, since it doesn't have a parent.
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
let 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 DOM tree nodes can be accessed directly as document
properties. For example, the <html>
element can be accessed with document.documentElement
property, whereas the <head>
element can be accessed with document.head
property, and the <body>
element can be accessed with document.body
property.
However, if you want to get only element nodes you can use the parentElement
, like this:
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
let hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Outputs: DIV
hint.parentNode.style.backgroundColor = "yellow";
</script>
Accessing the Sibling Nodes
You can use the previousSibling
and nextSibling
properties to access the previous and next node in the DOM tree, respectively. Here's an example:
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p><hr>
</div>
<script>
let title = document.getElementById("title");
alert(title.previousSibling.nodeName); // Outputs: #text
let hint = document.getElementById("hint");
alert(hint.nextSibling.nodeName); // Outputs: HR
</script>
Alternatively, you can use the previousElementSibling
and nextElementSibling
to get the previous and next sibling element skipping any whitespace text nodes. All these properties returns null
if there is no such sibling. Here's an example:
Example
Try this code »<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
let hint = document.getElementById("hint");
alert(hint.previousElementSibling.nodeName); // Outputs: H1
alert(hint.previousElementSibling.textContent); // Outputs: My Heading
let 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 text content of a node and all of its descendants. See the JavaScript DOM manipulation chapter to learn more about it.
Types of DOM Nodes
The DOM tree is consists of different types of nodes, such as elements, text, comments, etc.
Every node has a nodeType
property that you can use to find out what type of node you are dealing with. The following table lists the most important node types:
Constant | Value | Description |
---|---|---|
ELEMENT_NODE |
1 | An element node such as <p> or <img> . |
TEXT_NODE |
3 | The actual text of element. |
COMMENT_NODE |
8 | A comment node i.e. <!-- some comment --> |
DOCUMENT_NODE |
9 | A document node i.e. the parent of <html> element. |
DOCUMENT_TYPE_NODE |
10 | A document type node e.g. <!DOCTYPE html> for HTML5 documents. |