【问题标题】:Is there a way to select sibling nodes?有没有办法选择兄弟节点?
【发布时间】:2010-10-24 22:45:21
【问题描述】:

出于某些性能原因,我正在尝试找到一种仅选择所选节点的兄弟节点的方法。

例如,

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

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

【问题讨论】:

    标签: javascript dom siblings


    【解决方案1】:

    嗯...当然...只需访问父级,然后访问子级。

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

    【讨论】:

    • 请注意 jquery.siblings() 从结果集中排除当前节点。
    • 这是一个非常好的功能!
    • 其实jquery中node.parentNode.childNodes[]的等价物其实是$(node).parent().children()而不是$(node).siblings()。它可能是一个不错的功能,但也可能很烦人。这取决于你想要什么。
    • 你会想用 node.parentNode.childNodes 检查 ELEMENT_NODE 节点,因为它也会给你空白文本节点。
    • 没什么,我认为这是一个愚蠢的行为——对此感到抱歉(已删除)
    【解决方案2】:
    var sibling = node.nextSibling;
    

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

    [编辑]再想一想,这不会给出下一个div 标记,而是节点后面的空格。似乎更好

    var sibling = node.nextElementSibling;
    

    还有一个previousElementSibling

    【讨论】:

    【解决方案3】:

    快速:

    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)
    

    【讨论】:

    • 不错的解决方案。虽然,我会检查 nodeType 以丢弃文本节点 [ ...n.parentNode.children ].filter(c =&gt; c.nodeType == 1 &amp;&amp; c != n)
    • 你会如何为打字稿修改这个?
    【解决方案4】:

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

    从这里很容易得到所有下一个兄弟姐妹

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

    【讨论】:

    • 它应该返回所有兄弟姐妹,而不仅仅是nextprevious。在这种情况下,精确地指定向后或向前并没有多大帮助。
    • 为什么不呢。如果你采取下一个和上一个,你可以得到整个画面。这就是答案来展示一种新的做事方式。并为读者贡献一些东西。只是去父母并去每个元素并过滤每个人都可以做的当前元素
    【解决方案5】:

    你检查过 jQuery 中的“Sibling”方法吗?

        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!== 排除当前元素。

    我认为您可以使用相同的功能,所有代码似乎都是 vanilla 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/

      【讨论】:

        【解决方案7】:

        以下是获取上一个、下一个和所有兄弟姐妹(双方)的方法:

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

        【讨论】:

          【解决方案8】:

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

          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>

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

          【讨论】:

            【解决方案9】:

            使用document.querySelectorAll()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 &gt;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>

            【讨论】:

              【解决方案10】:

              jQuery

              $el.siblings();
              

              原生 - 最新,Edge13+

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

              Native(替代)- 最新,Edge13+

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

              原生 - IE10+

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

              【讨论】:

                【解决方案11】:
                var childNodeArray = document.getElementById('somethingOtherThanid').childNodes;
                

                【讨论】:

                【解决方案12】:

                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
                    }
                

                【讨论】:

                  【解决方案13】:

                  您可以使用currentNode.nextSibiling 属性访问以下兄弟节点。

                  这就是你可以在事件委托方式中做的事情,这是一种添加事件监听器的动态方式

                   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 */
                     }
                   })
                  

                  【讨论】:

                    【解决方案14】:
                    x1 = document.getElementById('outer')[0]
                          .getElementsByTagName('ul')[1]
                          .getElementsByTagName('li')[2];
                    x1.setAttribute("id", "buyOnlineLocationFix");
                    

                    【讨论】:

                      猜你喜欢
                      • 2018-08-06
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-08-02
                      • 2013-04-23
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多