Чи є спосіб вибрати вузли братів?


104

З якихось причин продуктивності я намагаюсь знайти спосіб виділити лише вузли братів вибраного вузла.

Наприклад,

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

Якщо я вибрав внутрішній вузол1, чи є мені спосіб отримати доступ до його побратимів, inner2-4вузлів?

Відповіді:


141

Ну ... точно ... просто зверніться до батьків, а потім до дітей.

 node.parentNode.childNodes[]

або ... за допомогою jQuery:

$('#innerId').siblings()

Редагувати: Клетус, як завжди, надихає. Я копав далі. Ось як 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 () виключає поточний вузол із набору результатів.
клент

3
Що дуже приємна особливість!
cgp

1
Насправді еквівалент node.parentNode.childNodes [] в jquery насправді $ (node) .parent (). Children () not $ (node) .siblings (). Це може бути приємною особливістю, але це також може дратувати. Це залежить від того, що ви хочете.
клетус

1
Ви хочете перевірити, чи немає вузлів ELEMENT_NODE за допомогою node.parentNode.childNodes, оскільки це також дасть вам текстові вузли пробілу.
seanmonstar

Нічого, я вважаю, що це був гуф - вибачте за це (видалено)
cgp

100
var sibling = node.nextSibling;

Це поверне побратимів одразу після нього, інакше вже не буде доступно більше братів і сестер. Так само можна використовувати previousSibling.

[Редагувати] По другій думці, це дасть не наступний divтег, а пробіл після вузла. Краще здається

var sibling = node.nextElementSibling;

Існує також а previousElementSibling.


1
наступний / попереднійElementSibling не підтримується в IE8
Вадим,

1
Починаючи з IE9 це так. Дивіться також stackoverflow.com/questions/5197825/…
parvus

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

Як би ви змінили це для typecript?
Нік Скоцзаро

10

З 2017 року:
пряма відповідь: element.nextElementSiblingдля отримання правильного елемента побратимів. також у вас є element.previousElementSiblingдля попереднього

звідси досить просто отримати всі наступні сибілінг

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

Він повинен повернути всіх братів і сестер, не тільки nextабо previous. Вказання того, що саме рухається назад або вперед, не дуже допомагає в цьому випадку.
dvlden

4
чому ні. якщо взяти наступний і попередній, ви можете отримати всю картину. ця відповідь приходить, щоб показати новий спосіб робити речі. і щось сприяти читачам. просто перейдіть на батьківщину і перейдіть кожен елемент і відфільтруйте поточний, який кожен може зробити
pery mimon

6

Ви перевірили метод "Брат" ("Sibling") в 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;
}

FYI: Кодова база jQuery - це чудовий ресурс для спостереження за Javascript 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 () та Loops та ітерацію

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");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.