Is there a way to select sibling nodes?

JavascriptDomSiblings

Javascript Problem Overview


For some performance reasons, I am trying to find a way to select only sibling nodes of the selected node.

For example,

<div id="outer">
  <div id="inner1"></div>
  <div id="inner2"></div>
  <div id="inner3"></div>
  <div id="inner4"></div>
</div>

If I selected inner1 node, is there a way for me to access its siblings, inner2-4 nodes?

Javascript Solutions


Solution 1 - Javascript

Well... sure... just access the parent and then the children.

 node.parentNode.childNodes[]

or... using jQuery:

$('#innerId').siblings()

Edit: Cletus as always is inspiring. I dug further. This is how jQuery gets siblings essentially:

function getChildren(n, skipMe){
	var r = [];
	for ( ; n; n = n.nextSibling ) 
       if ( n.nodeType == 1 && n != skipMe)
          r.push( n );        
	return r;
};

function getSiblings(n) {
    return getChildren(n.parentNode.firstChild, n);
}

Solution 2 - Javascript

var sibling = node.nextSibling;

This will return the sibling immediately after it, or null no more siblings are available. Likewise, you can use previousSibling.

[Edit] On second thought, this will not give the next div tag, but the whitespace after the node. Better seems to be

var sibling = node.nextElementSibling;

There also exists a previousElementSibling.

Solution 3 - Javascript

Quick:

var siblings = n => [...n.parentElement.children].filter(c=>c!=n)

https://codepen.io/anon/pen/LLoyrP?editors=1011

Get the parent's children as an array, filter out this element.

Edit:

And to filter out text nodes (Thanks pmrotule):

var siblings = n => [...n.parentElement.children].filter(c=>c.nodeType == 1 && c!=n)

Solution 4 - Javascript

From 2017:
straightforward answer: element.nextElementSibling for get the right element sibling. also you have element.previousElementSibling for previous one

from here is pretty simple to got all next sibiling

var n = element, ret = [];
while (n = n.nextElementSibling){
  ret.push(n)
}
return ret;

Solution 5 - Javascript

have you checked the "Sibling" method in jQuery?

    sibling: function( n, elem ) {
        var r = [];

        for ( ; n; n = n.nextSibling ) {
            if ( n.nodeType === 1 && n !== elem ) {
                r.push( n );
            }
        }

        return r;
    }

the n.nodeType == 1 check if the element is a html node and n!== exclude the current element.

I think you can use the same function, all that code seems to be vanilla javascript.

Solution 6 - Javascript

There are a few ways to do it.

Either one of the following should do the trick.

// METHOD A (ARRAY.FILTER, STRING.INDEXOF)
var siblings = function(node, children) {
    siblingList = children.filter(function(val) {
        return [node].indexOf(val) != -1;
    });
    return siblingList;
}

// METHOD B (FOR LOOP, IF STATEMENT, ARRAY.PUSH)
var siblings = function(node, children) {
    var siblingList = [];
    for (var n = children.length - 1; n >= 0; n--) {
        if (children[n] != node) {
            siblingList.push(children[n]);
        }  
    }
    return siblingList;
}

// METHOD C (STRING.INDEXOF, ARRAY.SPLICE)
var siblings = function(node, children) {
   siblingList = children;
   index = siblingList.indexOf(node);
   if(index != -1) {
       siblingList.splice(index, 1);
   }
   return siblingList;
}

FYI: The jQuery code-base is a great resource for observing Grade A Javascript.

Here is an excellent tool that reveals the jQuery code-base in a very streamlined way. http://james.padolsey.com/jquery/

Solution 7 - Javascript

The following function will return an array containing all the siblings of the given element.

const getSiblings = node => [...node.parentNode.children].filter(c => c !== node)

// get "c" element siblings (excluding itself)
const siblingsToC = getSiblings(document.querySelector('.c'))

console.log( siblingsToC )

<ul>
  <li class='a'>a</li>
  <li class='b'>b</li>
  <li class='c'>c</li>
  <li class='d'>d</li>
  <li class='e'>e</li>
</ul>

Just pass the selected element into the getSiblings() function as it's only parameter.

Solution 8 - Javascript

Use document.querySelectorAll() and Loops and iteration

function sibblingOf(children,targetChild){
  var children = document.querySelectorAll(children);
  for(var i=0; i< children.length; i++){
    children[i].addEventListener("click", function(){
      for(var y=0; y<children.length;y++){children[y].classList.remove("target")}
      this.classList.add("target")
    }, false)
  }
}

sibblingOf("#outer >div","#inner2");

#outer >div:not(.target){color:red}

<div id="outer">
      <div id="inner1">Div 1 </div>
      <div id="inner2">Div 2 </div>
      <div id="inner3">Div 3 </div>
      <div id="inner4">Div 4 </div>
 </div>

Solution 9 - Javascript

Here's how you could get previous, next and all siblings (both sides):

function prevSiblings(target) {
   var siblings = [], n = target;
   while(n = n.previousElementSibling) siblings.push(n);
   return siblings;
}

function nextSiblings(target) {
   var siblings = [], n = target;
   while(n = n.nextElementSibling) siblings.push(n);
   return siblings;
}

function siblings(target) {
    var prev = prevSiblings(target) || [],
        next = nexSiblings(target) || [];
    return prev.concat(next);
}

Solution 10 - Javascript

jQuery

$el.siblings();

Native - latest, Edge13+

[...el.parentNode.children].filter((child) =>
  child !== el
);

Native (alternative) - latest, Edge13+

Array.from(el.parentNode.children).filter((child) =>
  child !== el
);

Native - IE10+

Array.prototype.filter.call(el.parentNode.children, (child) =>
  child !== el
);

Solution 11 - Javascript

var childNodeArray = document.getElementById('somethingOtherThanid').childNodes;

Solution 12 - Javascript

  1. Add selected class to target element
    2) Find all children of parent element excluding target element
    3) Remove class from target element

    Div 1
    Div 2
    Div 3
    Div 4

    function getSiblings(target) { target.classList.add('selected'); let siblings = document.querySelecttorAll('#outer .item:not(.currentlySelected)') target.classList.remove('selected'); return siblings }

Solution 13 - Javascript

You can access the following sibling nodes, with the currentNode.nextSibiling property.

This is how you can do in the event delegation way, which is a dynamic way to add event listeners

 document.addEventListener('click', (event) => {
   if (event.target.matches("#inner1")) {
    console.log(event.targert.nextSibling); //inner2 div
    console.log(event.targert.nextSibling.nextSibling); //inner3 div 
    /* The more of the property you keep appending the further it goes to 
    the next sibling */
   }
 })

Solution 14 - Javascript

x1 = document.getElementById('outer')[0]
      .getElementsByTagName('ul')[1]
      .getElementsByTagName('li')[2];
x1.setAttribute("id", "buyOnlineLocationFix");

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncodingbearView Question on Stackoverflow
Solution 1 - JavascriptcgpView Answer on Stackoverflow
Solution 2 - JavascriptparvusView Answer on Stackoverflow
Solution 3 - JavascriptroundarView Answer on Stackoverflow
Solution 4 - Javascriptpery mimonView Answer on Stackoverflow
Solution 5 - JavascriptNicolas RojoView Answer on Stackoverflow
Solution 6 - JavascriptabbottoView Answer on Stackoverflow
Solution 7 - JavascriptSaabbirView Answer on Stackoverflow
Solution 8 - JavascriptGildas.TamboView Answer on Stackoverflow
Solution 9 - JavascriptMaciej SitkoView Answer on Stackoverflow
Solution 10 - JavascriptHumoyun AhmadView Answer on Stackoverflow
Solution 11 - JavascriptThunderboltzView Answer on Stackoverflow
Solution 12 - JavascriptManojView Answer on Stackoverflow
Solution 13 - JavascriptDanView Answer on Stackoverflow
Solution 14 - Javascriptandre paradiseView Answer on Stackoverflow