This content originally appeared on Envato Tuts+ Tutorials and was authored by Nitish Kumar
Recently I was working on a project that required me to add a class to all the siblings of an element if one of the siblings had that class. Similarly, I was required to show a pop up if an ancestor of the current element had a specific class. Traversing up, down or sideways in a DOM becomes important in a lot of situations when you are doing web development.
In this tutorial, I will show you to find the parents, children or siblings of an element using pure JavaScript without the need of any helper library.
The following HTML will be our reference for this tutorial:
1 |
<ol>
|
2 |
<li class="first-item"><p class="first-para"><span>Elephants</span> are the <span class="hlt">largest</span> existing land animals.</p></li> |
3 |
<li><p><span>Elephant</span> skin is <span class="important">2.5cm thick</span> on the back and <span>parts</span> of the <span>head</span>.</p></li> |
4 |
<li class="last-item"><p>About <span>60%</span> of an <span>Elephant's</span> weight is borne by its <span>front legs</span>.</p></li> |
5 |
</ol>
|
It contains three list items, each of which wraps around a paragraph. Every paragraph contains multiple span
elements. The first list item contains a span
tag that has the class hlt applied to it. We will be using this quite often in our tutorial.
Find the Parent of an Element
If you are actually looking for the immediate ancestor or parent of an element, you can simply check the value of the parentNode
or parentElement
property. Once you have the parent node or element, you can do further inspections with the help of properties like classList
or textContent
as shown below.
1 |
let hlt_span = document.querySelector(".hlt"); |
2 |
|
3 |
// Output: <p class="first-para"><span>Elephants</span> are the <span class="hlt">largest</span> existing land animals.</p>
|
4 |
console.log(hlt_span.parentElement); |
5 |
|
6 |
// Output: DOMTokenList [ "first-para" ]
|
7 |
console.log(hlt_span.parentElement.classList); |
8 |
|
9 |
// Output: Elephants are the largest existing land animals.
|
10 |
console.log(hlt_span.parentElement.textContent); |
Find Ancestors of Current Element
You can use the closest()
method if you want to traverse current element as well as all its ancestors up to the document root to find a particular element that matches the selector you specified as an argument to this method.
The closest()
method will return null
if there are no ancestors that match the passed selector. You will also get SyntaxError
if you don't want a valid CSS selector as an argument.
Here is an example:
1 |
let hlt_span = document.querySelector(".hlt"); |
2 |
|
3 |
// Output: <li class="first-item">
|
4 |
console.log(hlt_span.closest("li.first-item")); |
5 |
|
6 |
// Output: null
|
7 |
console.log(hlt_span.closest("li.last-item")); |
You can see in the above example that even though our markup contains a list element with class last-item
, it is not an ancestor of our span
tag with class hlt
. Therefore, a call to closest()
from our span element returns null
.
On the other hand, a call to closest()
with li.first-item
as selector does give us the first list item back.
Find the Children of Current Element
Just like the parentNode
or parentElement
property, there are similar properties called childNodes
and children
that you can use to get information about different child elements. The primary difference between these two is that childNodes
will give back elements, text and well as comment nodes. On the other hand, children
will only give back element nodes while skipping text or comment nodes.
1 |
let first_item = document.querySelector("li.first-item p"); |
2 |
|
3 |
// Output: NodeList(4) [ span, #text, span.hlt, #text ]
|
4 |
console.log(first_item.childNodes); |
5 |
|
6 |
// Output: HTMLCollection { 0: span, 1: span.hlt, length: 2 }
|
7 |
console.log(first_item.children); |
Let's say you are looking for a child span
element with class hlt
inside the first list item. You could iterate over all the child elements and then use the classList
property and its contains()
method to see if any of them have the specified class.
1 |
let first_item = document.querySelector("li.first-item p"); |
2 |
|
3 |
// Output: <span class="hlt">largest</span>
|
4 |
for(child of first_item.children) { |
5 |
if(child.classList.contains("hlt")){ |
6 |
console.log(child); |
7 |
}
|
8 |
}
|
Find a Descendant of Current Element
You are probably already familiar with the querySelector()
and querySelectorAll()
methods that can be called on the Document
object. These methods allow you to find any element within the document that matches the specified selector.
The same methods are also defined for the Element object and allow you to find any element which is a descendant of the calling element and matches the specified selector.
1 |
let list = document.querySelector("ol"); |
2 |
let list_spans = list.querySelectorAll("span"); |
3 |
|
4 |
// Output: 9
|
5 |
console.log(list_spans.length); |
6 |
|
7 |
// Output: <span class="important">2.5cm thick</span>
|
8 |
for(span of list_spans) { |
9 |
if(span.classList.contains("important")){ |
10 |
console.log(span); |
11 |
}
|
12 |
}
|
There were nine span
tags in our original markup that were descendants of the ordered list. You can see from the code above that all of them were present in list_spans
by checking that the value returned by the length
property is indeed 9
.
We iterate over all of these span
tags to find one which has the class important
applied to it.
You can also use querySelector()
and querySelectorAll()
to find the direct descendants or children of the calling element by passing :scope > selector
as the selector value for these methods. Here is an example:
1 |
let first_item = document.querySelector("p"); |
2 |
|
3 |
let direct_spans = first_item.querySelectorAll(":scope > span"); |
4 |
|
5 |
// Output: <span class="hlt">largest</span>
|
6 |
for(span of direct_spans) { |
7 |
if(span.classList.contains("hlt")){ |
8 |
console.log(span); |
9 |
}
|
10 |
}
|
Find the Next and Previous Siblings
Finding the next and previous sibling of an element is easy once you have a reference to its node. The next sibling can be found by using the nextSibling
property and the previous sibling can be found by using the previousSibling
property. You should note that both of these properties will also return any existing text nodes or comment nodes.
If you are only interested in finding the next or previous element nodes, you should consider using the nextElementSibling
and previousElementSibling
property. Here are some examples:
1 |
let important = document.querySelector(".important"); |
2 |
|
3 |
// Output: #text " skin is "
|
4 |
console.log(important.previousSibling); |
5 |
|
6 |
// Output: #text " on the back and "
|
7 |
console.log(important.nextSibling); |
8 |
|
9 |
// Output: <span>Elephant</span>
|
10 |
console.log(important.previousElementSibling); |
11 |
|
12 |
// Output: <span>parts</span>
|
13 |
console.log(important.nextElementSibling); |
Find All Siblings of an Element
A node instance also has a few other useful properties such as the parentElement
property which returns the parent element of the current DOM node. Once you have the parent element, you can use its children
property to get a live HTMLCollection
of all its child elements.
Once you have all the child elements, it is just a matter of iterating over them to exclude the element whose siblings we want to find and store all others in an array as shown below.
1 |
let important = document.querySelector(".important"); |
2 |
let all_children = important.parentElement.children; |
3 |
let siblings = []; |
4 |
|
5 |
// HTMLCollection { 0: span, 1: span.important, 2: span, 3: span, length: 4 }
|
6 |
console.log(all_children); |
7 |
|
8 |
for(child of all_children) { |
9 |
if(child != important) { |
10 |
siblings.push(child); |
11 |
}
|
12 |
}
|
13 |
|
14 |
// [<span>Elephant</span>, <span>parts</span>, <span>head</span>]
|
15 |
console.log(siblings); |
Find All the Previous Siblings of an Element
In this and the next section, we will learn how to get all the previous or next siblings of an element in JavaScript. I will like to use an ordered list for these examples with the names of some random people. Here is our markup:
1 |
<ol class="people"> |
2 |
<li>Adam</li> |
3 |
<li>Charles</li> |
4 |
<li>John</li> |
5 |
<li>Amanda</li> |
6 |
<li>Emma</li> |
7 |
<li>Emily</li> |
8 |
<li class="lawyer">Saul Goodman</li> |
9 |
<li>Hank</li> |
10 |
<li>Walter</li> |
11 |
<li>Skyler</li> |
12 |
<li>Jesse</li> |
13 |
</ol>
|
Our goal here is to go through the list of people and find all previous siblings of our list element with the class lawyer
.
The trick here is to get a reference to the lawyer element and then keep using previousElementSibling
to get the previous sibling until there is none left. This property will return null
when we reach the first element in the list.
1 |
let lawyer = document.querySelector(".lawyer"); |
2 |
|
3 |
let prev_siblings = []; |
4 |
|
5 |
let prev_elem = lawyer.previousElementSibling; |
6 |
|
7 |
while(prev_elem) { |
8 |
prev_siblings.push(prev_elem); |
9 |
prev_elem = prev_elem.previousElementSibling; |
10 |
}
|
11 |
|
12 |
// Array(6) [ li, li, li, li, li, li ]
|
13 |
console.log(prev_siblings); |
14 |
|
15 |
/*
|
16 |
Emily
|
17 |
Emma
|
18 |
Amanda
|
19 |
John
|
20 |
Charles
|
21 |
Adam
|
22 |
*/
|
23 |
for(sibling of prev_siblings) { |
24 |
console.log(sibling.textContent); |
25 |
}
|
Find All the Next Siblings of an Element
We can proceed in a similar manner to find all the next siblings of an element. The only change we need to make is the use of nextElementSibling
property instead of previousElementSibling
property. Here is an example:
1 |
let lawyer = document.querySelector(".lawyer"); |
2 |
|
3 |
let next_siblings = []; |
4 |
|
5 |
let next_elem = lawyer.nextElementSibling; |
6 |
|
7 |
while(next_elem) { |
8 |
next_siblings.push(next_elem); |
9 |
|
10 |
next_elem = next_elem.nextElementSibling; |
11 |
}
|
12 |
|
13 |
// Array(4) [ li, li, li, li ]
|
14 |
console.log(next_siblings); |
15 |
|
16 |
/*
|
17 |
Hank
|
18 |
Walter
|
19 |
Skyler
|
20 |
Jesse
|
21 |
*/
|
22 |
for(sibling of next_siblings) { |
23 |
console.log(sibling.textContent); |
24 |
}
|
Final Thoughts
Traversing the DOM to find the parents, ancestors, children, descendants or siblings of an element in now quite easy with JavaScript. You can simply use the properties parentElement
, children
, nextElementSibling
and previousElementSibling
to find the parent, children, next sibling or previous siblings of any element. You can also use the closest()
method if you are looking for a particular ancestor or you can use the querySelector()
method if you are looking for a particular descendant.
This content originally appeared on Envato Tuts+ Tutorials and was authored by Nitish Kumar
Nitish Kumar | Sciencx (2023-04-17T00:15:30+00:00) How to Find the Parents, Siblings, and Children of an Element Using the JavaScript DOM. Retrieved from https://www.scien.cx/2023/04/17/how-to-find-the-parents-siblings-and-children-of-an-element-using-the-javascript-dom/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.