In this article, weâre going to learn all about traversing DOM elements. When we traverse the DOM, weâre essentially navigating through the DOM. We work with parent, child and sibling properties to apply our JavaScript to DOM elements.
Let's use the following example:
<!DOCTYPE html>
<html>
<head>
<title>Traversing the DOM</title>
</head>
<body>
<h1>Traversing the DOM</h1>
<p>Let's work with this example to <strong>MASTER</strong> the DOM!</p>
<h2>List of Items..</h2>
<ul>
<li>Pizza</li>
<li>Burgers</li>
<li>Doritos</li>
</ul>
</body>
<script>
const h1 = document.getElementsByTagName('h1')[0];
const p = document.getElementsByTagName('p')[0];
const ul = document.getElementsByTagName('ul')[0];
</script>
</html>
Our file will open up in the browser like so:
Root Nodes
The document
 object is the root of every node in the DOM.* The next level up is the window
 object â which includes things such as *browser tabs, toolbars, prompts and alerts. Weâll be working with the DOM and thus the document
 object, which consists of what is inside of the inner window
.
By default, every document contains the html
, head
, and body
 elements.
Check the contents of each by running the following in your console:
document.head; // âş <head>...</head>
document.body; // âş <body>...</body>
Parent Nodes
As mentioned earlier, the nodes in the DOM are referred to as parents, children, and siblings, depending on their relation to other nodes. The parent of any particular node is the node that is one level above it in the DOM hierarchy.
In our example:
html
 is the parent ofÂhead
,Âbody
, andÂscript
.body
 is the parent ofÂh1
,Âh2
,Âp
 andÂul
, but notÂli
, asli
 is two levels down fromÂbody
.
We can check the parent of our p
 element for example, with the parentNode
 property. As weâve assigned p
 to a variable all we need to do is type:
p.parentNode; // âş <body>...</body>
We can even go two levels up with:
p.parentNode.parentNode; // âş <html>...</html>
Child Nodes
The children of a node are the nodes that are one level below. Any nodes beyond one level of nesting are usually referred to as descendants.
There are a number of properties weâll often be working with here, such as childNodes
, firstChild
, lastChild
, children
, firstElementChild
 and lastElementChild
.
Let's start with the childNodes
 property, it will return a list of every child of a given node:
ul.childNodes // âş NodeList(7) [text, li, text, li, text, li, text]
Perhaps you weâre expecting just three li
âs to be returned? The text
 nodes are actually whitespace caused by indentation between elements â which the DOM considers as nodes. You canât see them under your Elements tab, as Dev Tools removes these nodes automatically.
For this reason, if we attempt to alter the background color of the first child node for example, itâd fail as the first child is text.
ul.firstChild.style.background = "purple";
// output:
Uncaught TypeError: Cannot set property 'background' of undefined
When we want to work with element nodes only, we should use the children
, firstElementChild
 and lastElementChild
 properties.
ul.children
 would return only the three li
 elements.
And to change just our first li
, weâd use:
ul.firstElementChild.style.background = 'purple';
Hereâs our updated page:
If we want to alter all of our children
 elements, we could use a for...of
 loop like so:
for (let element of ul.children) {
element.style.background = 'purple';
}
Now all our child elements have the background color change:
If we take a look at our p
 element, weâll see it contains both text and other elements (our strong
 tag).
for (let element of p.childNodes) {
console.log(element);
}
// output:
"Let's work with this example to "
<strong>MASTER</strong>
" the DOM!"
The childNodes
 property is useful when we wish to access that information.
Both childNodes
 and children
 do not return traditional JavaScript arrays (with all their associated properties & methods), but rather array-like objects. As you would with an array, however, you can access nodes by index number, or even find their length
 property.
document.body.children[3].lastElementChild.style.background = 'pink';
With this code, weâll find the last element child li
 of the fourth child element ul
 of body
 and apply our style..
By using parent and child properties, you can retrieve any node in the DOM!
Sibling Nodes
Letâs now take a look at sibling nodes. Siblings of a node are any node on the same tree level in the DOM. They donât have to be the same type of node â text, element, and comment nodes can all be siblings. The properties weâll often work with here are nextSibling
, previousSibling
, nextElementSibling
 and previousElementSibling
.
Sibling properties work in the same way as child nodes:Â previousSibling
 and nextSibling
 will get the next node that immediately precedes or follows the specified node, and previousElementSibling
 and nextElementSibling
 will only get element nodes.
Letâ s get the middle element from our ul
:
const burger = ul.children[1];
And letâs use the element sibling properties to access the next and previous elements (avoiding the whitespace text):
burger.nextElementSibling.style.background = 'orange';
burger.previousElementSibling.style.background = 'green';
These changes will now show in our example:
In the next tutorial, weâll move on to making changes to the DOM. Stay tuned!
Related Posts:
A little about me..
Hey, Iâm Tim! đ
Iâm a freelance business owner, web developer & author. I teach both new and experienced freelancers how to build a sustainable and successful freelancing business. Check out my Complete Guide to Freelancing if you'd like to find out more.
While you're here, you can browse through my blogs where I post freelancing tips, code tutorials, design inspiration, useful tools & resources, and much more! You can also join the newsletter, or find me on X.
Thanks for reading! đ