有没有办法选择兄弟节点?

cod*_*ear 86 javascript dom siblings

出于某些性能原因,我试图找到一种方法来仅选择所选节点的兄弟节点.例如,

 <div id="outer">
      <div id="inner1"> </div>
      <div id="inner2"> </div>
      <div id="inner3"> </div>
      <div id="inner4"> </div>
 </div>
Run Code Online (Sandbox Code Playgroud)

如果我选择了inner1节点,有没有办法让我访问它的兄弟inner2-4节点?

cgp*_*cgp 126

嗯...确定......只需访问父母,然后访问孩子.

 node.parentNode.childNodes[]
Run Code Online (Sandbox Code Playgroud)

或者......使用jQuery:

$('#innerId').siblings()
Run Code Online (Sandbox Code Playgroud)

编辑: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);
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,jquery.siblings()从结果集中排除当前节点. (22认同)
  • 这是一个非常好的功能! (3认同)
  • 好吧,好吧,我不再懒惰,挖出代码! (2认同)

par*_*vus 91

var sibling = node.nextSibling;
Run Code Online (Sandbox Code Playgroud)

这将在它之后立即返回兄弟,或者不再有兄弟姐妹可用.同样,你可以使用previousSibling.

[编辑]第二个想法,这不会给出下一个div标签,而是节点后的空白.似乎更好

var sibling = node.nextElementSibling;
Run Code Online (Sandbox Code Playgroud)

还有一个previousElementSibling.


rou*_*dar 11

快:

var siblings = n => [...n.parentElement.children].filter(c=>c!=n)
Run Code Online (Sandbox Code Playgroud)

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

将父项的子项作为数组获取,过滤掉该元素.

编辑:

并筛选出文本节点(Thanks pmrotule):

var siblings = n => [...n.parentElement.children].filter(c=>c.nodeType == 1 && c!=n)
Run Code Online (Sandbox Code Playgroud)

  • @pmrotule [Element.children](https://developer.mozilla.org/en-US/docs/Web/API/Element/children) 直接仅返回元素子级,因此按节点类型过滤是多余的。 (3认同)
  • 不错的解决方案。虽然,我会检查nodeType以丢弃文本节点`[... n.parentNode.children] .filter(c =&gt; c.nodeType == 1 &amp;&amp; c!= n)` (2认同)

per*_*mon 7

从2017年开始:
直截了当的回答:element.nextElementSibling为了获得正确的元素兄弟.你也有element.previousElementSibling前一个

从这里获得所有下一个兄弟姐妹非常简单

var n = element, ret = [];
while (n = n.nextElementSibling){
  ret.push(n)
}
return ret;
Run Code Online (Sandbox Code Playgroud)

  • 为什么不.如果你采取下一个和以前的,你可以得到全貌.这个答案来展示一种新的做事方式.并为读者贡献一些东西.只是去父母,去每个元素,过滤每个人都可以做的当前元素 (3认同)

Nic*_*ojo 6

你有没有检查过jQuery中的"兄弟姐妹"方法?

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

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

        return r;
    }
Run Code Online (Sandbox Code Playgroud)

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

我认为你可以使用相同的功能,所有代码似乎都是vanilla javascript.


abb*_*tto 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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


Saa*_*bir 5

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

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 )
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

只需将所选元素getSiblings()作为唯一参数传递到函数中即可。