Есть ли способ выбрать одноуровневые узлы?


по некоторым причинам производительности я пытаюсь найти способ выбрать только одноуровневые узлы выбранного узла. Например,

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

Если я выбрал узел inner1, есть ли способ для меня получить доступ к его братьям и сестрам,inner2-4 узлы?

10 69

10 ответов:

хорошо... конечно... просто получите доступ к родителю, а затем к детям.

 node.parentNode.childNodes[]

или... с помощью jQuery:

$('#innerId').siblings()

Edit: Клетус, как всегда, вдохновляет. Я копнул дальше. Вот как 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);
}
var sibling = node.nextSibling;

это вернет брата сразу после него, или null больше не доступны братья и сестры. Кроме того, вы можете использовать previousSibling.

[Edit] на второй мысли, это не даст следующий div - тег, но пробел после точки. Лучше, вроде бы

var sibling = node.nextElementSibling;

есть previousElementSibling.

есть несколько способов сделать это.

либо один из следующих должен сделать трюк.

// 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 является отличным ресурсом для наблюдения класс В JavaScript.

вот отличный инструмент, который показывает кодовую базу jQuery очень упрощенным способом. http://james.padolsey.com/jquery/

быстрый:

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

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

получить дочерние элементы родителя в виде массива, отфильтровать этот элемент.

Edit:

и отфильтровать текстовые узлы (спасибо pmrotule):

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

вы проверили метод" брат " в 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.

С 2017 года:
прямой ответ:element.nextElementSibling для получения правильного элемента sibling. также у вас есть element.previousElementSibling для предыдущего

отсюда довольно просто получить все следующие sibiling

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

вот как вы могли бы получить предыдущий, следующий и все братья и сестры (с обеих сторон):

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

использовать документ.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>
var childNodeArray = document.getElementById('somethingOtherThanid').childNodes;
x1 = document.getElementById('outer')[0]
      .getElementsByTagName('ul')[1]
      .getElementsByTagName('li')[2];
x1.setAttribute("id", "buyOnlineLocationFix");