In the previous article, we looked at how to get the next and previous siblings of an element in JavaScript.
What if you want to select all siblings of an element?
Let us say you have the following HTML list:
<ul>
<li>🍔</li>
<li>🍕</li>
<li id="drink">🍹</li>
<li>🍲</li>
<li>🍩</li>
</ul>
We want to get the #drink
element, and then locate all of its sibling elements.
The following helper function takes an element as input and returns all of its siblings:
const siblings = (elem) => {
// create an empty array
let siblings = [];
// if no parent, return empty list
if (!elem.parentNode) {
return siblings;
}
// first child of the parent node
let sibling = elem.parentNode.firstElementChild;
// loop through next siblings until `null`
do {
// push sibling to array
if (sibling != elem) {
siblings.push(sibling);
}
} while (sibling = sibling.nextElementSibling);
return siblings;
};
const drink = document.querySelector('#drink');
// get all all siblings
const nodes = siblings(drink);
nodes.forEach(li => console.log(li.innerText));
// 🍔
// 🍕
// 🍲
// 🍩
Here is how it works:
- Get the parent of the element who's siblings we wan to find.
- Find the first element child inside that parent element.
- Add the first element child to an array of siblings.
- Select the next sibling of the first element.
- Finally, repeat the 3rd and 4th steps until there are no siblings left. In case the sibling is the original element, skip the 3rd step.
Filter siblings
Sometimes, you may want to filter out the siblings of an element. For example, you may want to get all siblings of a node that are the anchor links (<a>
).
To do this, you can pass an optional filer function to the helper function as shown below:
const siblings = (elem, filter) => {
// create an empty array
let siblings = [];
// if no parent, return empty list
if (!elem.parentNode) {
return siblings;
}
// first child of the parent node
let sibling = elem.parentNode.firstElementChild;
// loop through next siblings until `null`
do {
// push sibling to array
if (sibling != elem && (!filter || filter(sibling))) {
siblings.push(sibling);
}
} while (sibling = sibling.nextElementSibling);
return siblings;
};
The following example demonstrates how you can use the siblings()
helper function to get all the siblings of an anchor element, which are also anchor nodes:
const anchor = document.querySelector('a.current');
// get all anchor links
const links = siblings(anchor, (e) => {
return e.nodeName.toLowerCase() === 'a';
});
links.forEach(a => console.log(a.href));
Whitespace and comments
The above helper function relies on the nextElementSibling
property that returns the next element node by ignoring whitespace and comments.
If you want to get all siblings, including whitespace and comments, use the nextSibling
property instead. It returns the next sibling node that might be a text node (whitespace) or a comment node.
Browser compatibility
The above helper function should work in all modern browsers and IE9 and up.
✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.