Apakah ada cara untuk memilih node saudara?


104

Untuk beberapa alasan kinerja, saya mencoba menemukan cara untuk memilih hanya simpul saudara dari simpul yang dipilih.

Sebagai contoh,

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

Jika saya memilih node inner1, apakah ada cara bagi saya untuk mengakses saudara kandungnya, inner2-4node?

Jawaban:


141

Baiklah ... tentu ... akses saja orang tua dan kemudian anak-anak.

 node.parentNode.childNodes[]

atau ... menggunakan jQuery:

$('#innerId').siblings()

Sunting: Cletus seperti biasa menginspirasi. Saya menggali lebih jauh. Inilah cara jQuery mendapatkan saudara pada dasarnya:

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
Perhatikan bahwa jquery.siblings () mengecualikan node saat ini dari set hasil.
cletus

3
Yang merupakan fitur yang sangat bagus!
cgp

1
Sebenarnya padanan node.parentNode.childNodes [] di jquery sebenarnya $ (node) .parent (). Children () bukan $ (node) .siblings (). Ini bisa menjadi fitur yang bagus tetapi juga bisa mengganggu. Itu tergantung pada apa yang Anda inginkan.
cletus

1
Anda akan ingin memeriksa node ELEMENT_NODE dengan node.parentNode.childNodes, karena itu akan memberi Anda node teks ruang putih juga.
seanmonstar

Tidak ada, saya pikir itu adalah kesalahan - maaf tentang itu (dihapus)
cgp

100
var sibling = node.nextSibling;

Ini akan mengembalikan saudara segera setelahnya, atau null tidak ada saudara lagi yang tersedia. Demikian juga, Anda bisa menggunakan previousSibling.

[Sunting] Setelah dipikir-pikir, ini tidak akan memberikan divtag berikutnya , tetapi spasi setelah node. Sepertinya lebih baik

var sibling = node.nextElementSibling;

Ada juga ada previousElementSibling .


1
next / beforeElementSibling tidak didukung di IE8
Vadim

1
Mulai dari IE9. Lihat juga stackoverflow.com/questions/5197825/…
parvus

14

Cepat:

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

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

Dapatkan turunan orang tua sebagai array, filter elemen ini.

Edit:

Dan untuk menyaring node teks (Terima kasih pmrotule ):

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

2
Solusi bagus. Meskipun, saya akan memeriksa nodeType untuk membuang node teks[ ...n.parentNode.children ].filter(c => c.nodeType == 1 && c != n)
pmrotule

Bagaimana Anda memodifikasi ini untuk skrip ketikan?
Nic Scozzaro

10

Dari 2017:
jawaban langsung: element.nextElementSiblinguntuk mendapatkan saudara elemen yang tepat. juga Anda miliki element.previousElementSiblinguntuk yang sebelumnya

dari sini cukup mudah untuk mendapatkan semua saudara kandung berikutnya

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

Ini harus mengembalikan semua saudara kandung, tidak hanya nextatau previous. Menentukan secara tepat mundur atau maju tidak banyak membantu dalam kasus ini.
dvlden

4
kenapa tidak. jika Anda mengambil gambar berikutnya dan sebelumnya, Anda bisa mendapatkan gambaran keseluruhan. jawaban itu datang untuk menunjukkan cara baru dalam melakukan sesuatu. dan menyumbangkan sesuatu untuk pembaca. hanya untuk menjadi orang tua dan pergi ke setiap elemen dan memfilter yang saat ini dapat dilakukan semua orang
pery mimon

6

sudahkah Anda memeriksa metode "Sibling" di 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 periksa apakah elemennya adalah node html dan n! == mengecualikan elemen saat ini.

Saya pikir Anda dapat menggunakan fungsi yang sama, semua kode itu tampaknya javascript vanilla.


6

Ada beberapa cara untuk melakukannya.

Salah satu dari yang berikut ini seharusnya berhasil.

// 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: Basis kode jQuery adalah sumber daya yang bagus untuk mengamati JavaScript Tingkat A.

Berikut adalah alat luar biasa yang mengungkapkan basis kode jQuery dengan cara yang sangat efisien. http://james.padolsey.com/jquery/


3

Inilah cara Anda mendapatkan saudara sebelumnya, berikutnya, dan semua (kedua sisi):

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

Gunakan document.querySelectorAll () dan Loop dan iterasi

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

Asli - terbaru, Edge13 +

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

Asli (alternatif) - terbaru, Edge13 +

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

Asli - IE10 +

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


0

1) Tambahkan kelas yang dipilih ke elemen target
2) Temukan semua turunan dari elemen induk tidak termasuk elemen target
3) Hapus kelas dari elemen target

 <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

Fungsi berikut akan mengembalikan larik yang berisi semua saudara kandung dari elemen yang diberikan.

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

Cukup berikan elemen yang dipilih ke dalam getSiblings()fungsi sebagai satu-satunya parameter.


-2
x1 = document.getElementById('outer')[0]
      .getElementsByTagName('ul')[1]
      .getElementsByTagName('li')[2];
x1.setAttribute("id", "buyOnlineLocationFix");
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.