Có cách nào để chọn các nút anh chị em?


104

Vì một số lý do về hiệu suất, tôi đang cố gắng tìm cách chỉ chọn các nút anh em của nút đã chọn.

Ví dụ,

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

Nếu tôi đã chọn nút inner1, có cách nào để tôi truy cập vào các inner2-4nút anh chị em của nó không?

Câu trả lời:


141

Vâng ... chắc chắn ... chỉ cần truy cập cha mẹ và sau đó là con cái.

 node.parentNode.childNodes[]

hoặc ... sử dụng jQuery:

$('#innerId').siblings()

Chỉnh sửa: Cletus luôn là nguồn cảm hứng. Tôi đã đào sâu hơn. Đây là cách jQuery nhận được anh chị em về cơ bản:

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
Lưu ý rằng jquery.siblings () loại trừ nút hiện tại khỏi tập kết quả.
cletus

3
Đó là một tính năng rất hay!
cgp

1
Trên thực tế, tương đương của node.parentNode.childNodes [] trong jquery thực sự là $ (node) .parent (). Children () chứ không phải $ (node) .siblings (). Nó có thể là một tính năng hay nhưng nó cũng có thể gây khó chịu. Nó phụ thuộc vào những gì bạn muốn.
cletus

1
Bạn sẽ muốn kiểm tra các nút ELEMENT_NODE bằng node.parentNode.childNodes, vì nó cũng sẽ cung cấp cho bạn các nút văn bản khoảng trắng.
seanmonstar

Không có gì, tôi nghĩ đó là một trò ngu ngốc - xin lỗi về điều đó (đã bị xóa)
cgp 20/02/15

100
var sibling = node.nextSibling;

Điều này sẽ trả lại anh chị em ngay sau nó, hoặc vô hiệu hóa không còn anh chị em nào nữa. Tương tự như vậy, bạn có thể sử dụng previousSibling.

[Chỉnh sửa] Suy nghĩ thứ hai, điều này sẽ không cung cấp divthẻ tiếp theo , mà là khoảng trắng sau nút. Có vẻ tốt hơn là

var sibling = node.nextElementSibling;

Cũng tồn tại a previousElementSibling.


1
tiếp theo / previousElementSibling không được hỗ trợ trong IE8
Vadim

1
Bắt đầu từ IE9 nó là. Xem thêm stackoverflow.com/questions/5197825/…
parvus

14

Nhanh chóng:

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

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

Lấy con của cha mẹ dưới dạng một mảng, lọc bỏ phần tử này.

Biên tập:

Và để lọc ra các nút văn bản (Cảm ơn pmrotule ):

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

2
Giải pháp tốt. Mặc dù, tôi sẽ kiểm tra cho nodeType đến nút văn bản loại bỏ[ ...n.parentNode.children ].filter(c => c.nodeType == 1 && c != n)
pmrotule

Làm thế nào bạn sẽ sửa đổi điều này cho bản đánh chữ?
Nic Scozzaro

10

Từ năm 2017:
câu trả lời đơn giản: element.nextElementSiblingđể có được phần tử phù hợp. bạn cũng có element.previousElementSiblingcái trước

từ đây khá đơn giản để có tất cả các sibiling tiếp theo

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

Nó sẽ trả lại tất cả anh chị em, không chỉ nexthoặc previous. Việc chỉ định chính xác đi lùi hoặc tiến không giúp ích nhiều trong trường hợp này.
dvlden

4
tại sao không. nếu bạn chụp tiếp theo và trước đó, bạn có thể có được toàn bộ hình ảnh. đó là câu trả lời cho thấy một cách mới để làm mọi việc. và đóng góp gì đó cho độc giả. chỉ để đi phụ huynh và đi từng yếu tố và lọc một tất cả mọi người hiện tại có thể làm
Pery Mimon

6

bạn đã kiểm tra phương thức "Sibling" trong jQuery chưa?

    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 kiểm tra xem phần tử có phải là nút html hay không và n! == loại trừ phần tử hiện tại.

Tôi nghĩ bạn có thể sử dụng cùng một chức năng, tất cả mã đó dường như là javascript vani.


6

Có một số cách để làm điều đó.

Một trong những cách sau sẽ thực hiện thủ thuật.

// 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: Cơ sở mã jQuery là một nguồn tài nguyên tuyệt vời để quan sát Javascript Hạng A.

Đây là một công cụ tuyệt vời tiết lộ cơ sở mã jQuery theo một cách rất hợp lý. http://james.padolsey.com/jquery/


3

Đây là cách bạn có thể nhận được trước, sau và tất cả anh chị em (cả hai bên):

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

Sử dụng document.querySelectorAll ()Loops và phép lặp

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

Gốc - mới nhất, Edge13 +

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

Gốc (thay thế) - mới nhất, Edge13 +

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

Bản địa - IE10 +

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


0

1) Thêm lớp đã chọn vào phần tử đích
2) Tìm tất cả các phần tử con của phần tử mẹ trừ phần tử đích
3) Xóa lớp khỏi phần tử đích

 <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

Hàm sau sẽ trả về một mảng chứa tất cả các anh chị em của phần tử đã cho.

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

Chỉ cần truyền phần tử đã chọn vào getSiblings()hàm vì nó là tham số duy nhất.


-2
x1 = document.getElementById('outer')[0]
      .getElementsByTagName('ul')[1]
      .getElementsByTagName('li')[2];
x1.setAttribute("id", "buyOnlineLocationFix");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.