มีวิธีเลือกโหนดพี่น้องหรือไม่?


110

ด้วยเหตุผลด้านประสิทธิภาพบางประการฉันกำลังพยายามหาวิธีเลือกเฉพาะโหนดพี่น้องของโหนดที่เลือก

ตัวอย่างเช่น,

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

หากฉันเลือกโหนด inner1 มีวิธีให้ฉันเข้าถึงinner2-4โหนดพี่น้องหรือไม่

คำตอบ:


146

ดี ... แน่นอน ... เพียงแค่เข้าถึงผู้ปกครองและเด็ก ๆ

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

23
โปรดสังเกตว่า jquery.siblings () ไม่รวมโหนดปัจจุบันจากชุดผลลัพธ์
cletus

3
ซึ่งเป็นคุณสมบัติที่ดีมาก!
cgp

1
จริงๆแล้วสิ่งที่เทียบเท่ากับ node.parentNode.childNodes [] ใน jquery คือ $ (node) .parent (). children () ไม่ใช่ $ (node) .siblings () อาจเป็นคุณสมบัติที่ดี แต่ก็อาจสร้างความรำคาญได้เช่นกัน มันขึ้นอยู่กับสิ่งที่คุณต้องการ
cletus

1
คุณจะต้องตรวจสอบโหนด ELEMENT_NODE ด้วย node.parentNode.childNodes เพราะจะให้โหนดพื้นที่สีขาวแก่คุณด้วย
seanmonstar

ไม่มีอะไรฉันคิดว่ามันเป็นความผิด - ขอโทษเกี่ยวกับเรื่องนี้ (ลบออก)
cgp

104
var sibling = node.nextSibling;

สิ่งนี้จะส่งคืนพี่น้องทันทีหลังจากนั้นหรือไม่มีพี่น้องอีกต่อไป previousSiblingในทำนองเดียวกันคุณสามารถใช้

[แก้ไข]ในความคิดที่สองสิ่งนี้จะไม่ให้divแท็กถัดไปแต่เป็นช่องว่างหลังโหนด น่าจะดีกว่า

var sibling = node.nextElementSibling;

นอกจากนี้ยังมีไฟล์previousElementSibling.


1
next / previousElementSibling ไม่รองรับใน IE8
Vadim

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

คุณจะแก้ไขสิ่งนี้สำหรับ typescript ได้อย่างไร?
Nic Scozzaro

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! == ไม่รวมองค์ประกอบปัจจุบัน

ฉันคิดว่าคุณสามารถใช้ฟังก์ชั่นเดียวกันรหัสทั้งหมดนั้นน่าจะเป็นวานิลลาจาวาสคริปต์


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 code-base เป็นแหล่งข้อมูลที่ยอดเยี่ยมสำหรับการสังเกต Javascript เกรด A

นี่คือเครื่องมือที่ยอดเยี่ยมที่เปิดเผยฐานรหัส 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 ()และลูปและการวนซ้ำ

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

Native - ล่าสุด 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
);

0
var childNodeArray = document.getElementById('somethingOtherThanid').childNodes;

window.document.documentElement.childNodes [1] .childNodes [4] คัดมาจากhowtocreate.co.uk/tutorials/javascript/dombasics
Thunderboltz

เป็นทางออกของคำถามหรือไม่?
zahid9i

สิ่งนี้ไม่ได้ช่วยแก้ปัญหาในมือหรืออย่างน้อยก็ไม่ชัดเจนเพียงพอที่จะเป็นประโยชน์
cdeszaq

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
    }

0

ฟังก์ชันต่อไปนี้จะส่งคืนอาร์เรย์ที่มีพี่น้องทั้งหมดขององค์ประกอบที่กำหนด

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

เพียงแค่ส่งองค์ประกอบที่เลือกไปยังgetSiblings()ฟังก์ชันเนื่องจากเป็นพารามิเตอร์เท่านั้น


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.