Gibt es eine Möglichkeit, Geschwisterknoten auszuwählen?


104

Aus bestimmten Leistungsgründen versuche ich, nur Geschwisterknoten des ausgewählten Knotens auszuwählen.

Beispielsweise,

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

Wenn ich inner1 node ausgewählt habe, gibt es eine Möglichkeit für mich, auf seine Geschwister, inner2-4Knoten , zuzugreifen ?

Antworten:


141

Nun ... sicher ... greifen Sie einfach auf die Eltern und dann auf die Kinder zu.

 node.parentNode.childNodes[]

oder ... mit jQuery:

$('#innerId').siblings()

Edit: Cletus ist wie immer inspirierend. Ich grub weiter. So bekommt jQuery im Wesentlichen Geschwister:

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
Beachten Sie, dass jquery.scriber () den aktuellen Knoten aus der Ergebnismenge ausschließt.
Cletus

3
Welches ist eine sehr schöne Funktion!
CGP

1
Tatsächlich ist das Äquivalent von node.parentNode.childNodes [] in jquery wirklich $ (node) .parent (). Children (), nicht $ (node) .s Geschwisters (). Es kann eine nette Funktion sein, aber es kann auch ärgerlich sein. Es kommt darauf an, was Sie wollen.
Cletus

1
Sie möchten mit node.parentNode.childNodes nach ELEMENT_NODE-Knoten suchen, da Sie dadurch auch Leerzeichen-Textknoten erhalten.
Seanmonstar

Nichts, ich denke, es war ein Trottel - Entschuldigung (entfernt)
cgp

100
var sibling = node.nextSibling;

Dadurch wird das Geschwister sofort danach zurückgegeben, oder null, es sind keine Geschwister mehr verfügbar. Ebenso können Sie verwenden previousSibling.

[Bearbeiten] Beim zweiten Gedanken gibt dies nicht das nächste divTag, sondern das Leerzeichen nach dem Knoten. Besser scheint es zu sein

var sibling = node.nextElementSibling;

Es gibt auch eine previousElementSibling.


1
next / previousElementSibling wird in IE8
Vadim

1
Ab IE9 ist es. Siehe auch stackoverflow.com/questions/5197825/…
parvus

14

Schnell:

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

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

Holen Sie sich die untergeordneten Elemente der Eltern als Array und filtern Sie dieses Element heraus.

Bearbeiten:

Und um Textknoten herauszufiltern (Danke pmrotule ):

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

2
Schöne Lösung. Obwohl ich nach nodeType suchen würde, um Textknoten zu verwerfen[ ...n.parentNode.children ].filter(c => c.nodeType == 1 && c != n)
pmrotule

Wie würden Sie dies für Typoskript ändern?
Nic Scozzaro

10

Ab 2017:
unkomplizierte Antwort: element.nextElementSiblingFür das richtige Element Geschwister. auch du hast element.previousElementSiblingfür vorheriges

Von hier aus ist es ziemlich einfach, alle nächsten Geschwister zu bekommen

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

Es sollte alle Geschwister zurückgeben, nicht nur nextoder previous. In diesem Fall hilft es nicht viel, genau vorwärts oder rückwärts zu gehen.
dvlden

4
warum nicht. Wenn Sie das nächste und das vorherige aufnehmen, können Sie das ganze Bild erhalten. Diese Antwort zeigt einen neuen Weg, Dinge zu tun. und etwas zu den Lesern beitragen. Nur um Eltern zu werden und jedes Element zu gehen und das aktuelle zu filtern, das jeder tun kann
pery mimon

6

Haben Sie die Methode "Geschwister" in jQuery überprüft?

    sibling: function( n, elem ) {
        var r = [];

        for ( ; n; n = n.nextSibling ) {
            if ( n.nodeType === 1 && n !== elem ) {
                r.push( n );
            }
        }

        return r;
    }

Der n.nodeType == 1 prüft, ob das Element ein HTML-Knoten ist, und n! == schließt das aktuelle Element aus.

Ich denke, Sie können die gleiche Funktion verwenden, der gesamte Code scheint Vanille-Javascript zu sein.


6

Es gibt verschiedene Möglichkeiten, dies zu tun.

Eine der folgenden Möglichkeiten sollte ausreichen.

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

Zu Ihrer Information: Die jQuery-Codebasis ist eine großartige Ressource für die Beobachtung von Javascript der Klasse A.

Hier ist ein hervorragendes Tool, das die jQuery-Codebasis auf sehr optimierte Weise anzeigt. http://james.padolsey.com/jquery/


3

So könnten Sie vorherige, nächste und alle Geschwister (beide Seiten) bekommen:

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

Verwenden Sie document.querySelectorAll () und Loops und Iteration

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 - neueste Version, Edge13 +

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

Native (Alternative) - neueste Version, Edge13 +

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

Native - IE10 +

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


0

1) Fügen Sie dem Zielelement eine ausgewählte Klasse hinzu.
2) Suchen Sie alle untergeordneten Elemente des übergeordneten Elements mit Ausnahme des Zielelements.
3) Entfernen Sie die Klasse aus dem Zielelement

 <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

Die folgende Funktion gibt ein Array zurück, das alle Geschwister des angegebenen Elements enthält.

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

Übergeben Sie einfach das ausgewählte Element getSiblings()als einzigen Parameter an die Funktion.


-2
x1 = document.getElementById('outer')[0]
      .getElementsByTagName('ul')[1]
      .getElementsByTagName('li')[2];
x1.setAttribute("id", "buyOnlineLocationFix");
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.