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:

  1. Get the parent of the element who's siblings we wan to find.
  2. Find the first element child inside that parent element.
  3. Add the first element child to an array of siblings.
  4. Select the next sibling of the first element.
  5. 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.