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