Is there a way to select sibling nodes?
JavascriptDomSiblingsJavascript 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
-
Add selected class to target element
2) Find all children of parent element excluding target element
3) Remove class from target elementDiv 1Div 2Div 3Div 4function 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");