有没有办法选择同级节点?


104

由于某些性能原因,我试图找到一种仅选择所选节点中同级节点的方法。

例如,

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

如果我选择了inner1节点,是否有办法访问其兄弟inner2-4节点?

Answers:


141

好吧...确定...先拜访父母,再拜访孩子。

 node.parentNode.childNodes[]

或者...使用jQuery:

$('#innerId').siblings()

编辑:Cletus一如既往地鼓舞人心。我进一步挖掘。jQuery本质上就是这样获得兄弟姐妹的:

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);
}

23
请注意,jquery.siblings()从结果集中排除当前节点。
cletus

3
这是一个非常不错的功能!
cgp

1
实际上,jquery中的node.parentNode.childNodes []等同于$(node).parent()。children()而不是$(node).siblings()。这可能是一个不错的功能,但也可能很烦人。这取决于您想要什么。
cletus

1
您将要检查是否具有node.parentNode.childNodes的ELEMENT_NODE节点,因为它也会为您提供空白文本节点。
seanmonstar

没什么,我认为这是愚蠢的事-对此表示抱歉(已删除)
cgp 2015年

100
var sibling = node.nextSibling;

这将在其后立即返回同级,或者null不再有可用的同级。同样,您可以使用previousSibling

[编辑]再三考虑,这不会给出下一个div标签,而是节点后的空白。更好的似乎是

var sibling = node.nextElementSibling;

也存在一个previousElementSibling


1
IE8不支持next / previousElementSibling
Vadim 2014年


14

快:

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

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

获取父母的孩子作为一个数组,过滤掉这个元素。

编辑:

并过滤掉文本节点(感谢pmrotule):

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

2
不错的解决方案。虽然,我会检查nodeType以丢弃文本节点[ ...n.parentNode.children ].filter(c => c.nodeType == 1 && c != n)
pmrotule,

您如何修改打字稿?
Nic Sc​​ozzaro

10

从2017年开始:
简单的答案:element.nextElementSibling获得正确的元素同级。你也有element.previousElementSibling上一个

从这里很容易得到所有下一次嘲笑

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

它应该返回所有同级,不仅是nextprevious。在这种情况下,准确指定前进或后退并没有太大帮助。
dvlden

4
为什么不。如果您拍摄下一个和上一个,则可以得到完整的图片。答案就是显示一种新的做事方式。并为读者做出贡献。只是去做父母,去每个元素,过滤每个人都可以做的事
pery mimon 17/09/24

6

您是否检查过jQuery中的“同级”方法?

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

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

        return r;
    }

n.nodeType == 1检查该元素是否为html节点,并且n!==排除当前元素。

我认为您可以使用相同的功能,所有这些代码似乎都是普通的javascript。


6

有几种方法可以做到这一点。

以下任一方法都可以解决问题。

// 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;
}

仅供参考:jQuery代码库是观察A级Javascript的绝佳资源。

这是一个非常出色的工具,可以非常简化地显示jQuery代码库。 http://james.padolsey.com/jquery/


3

这是获取上一个,下一个和所有同级兄弟(双方)的方式:

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);
}

2

使用document.querySelectorAll()以及循环和迭代

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>


1

jQuery的

$el.siblings();

原生-最新的Edge13 +

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

本机(替代)-最新,Edge13 +

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

原生-IE10 +

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


0

1)将选定的类添加到目标元素
2)查找父元素中除目标元素之外的所有子元素
3)从目标元素中删除类

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



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

-1

以下函数将返回一个包含给定元素的所有同级元素的数组。

function getSiblings(elem) {
    return [...elem.parentNode.children].filter(item => item !== elem);
}

只需将选定的元素getSiblings()作为唯一参数传递给函数即可。


-2
x1 = document.getElementById('outer')[0]
      .getElementsByTagName('ul')[1]
      .getElementsByTagName('li')[2];
x1.setAttribute("id", "buyOnlineLocationFix");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.