Orlok: Bei Click oder mouseover auf kleinem Bild Vergrößerung anzeigen.

Beitrag lesen

Hallo Henry

Hier funktioniert nextSibling, weil kein Leerzeichen/Absatz dazwischen ist. Manche Browser (weiß nicht ob alle) interpretieren dann die Leerstelle als nächstes.

Wenn du einen Browser findest der den Whitespace nicht interpretiert, solltest du den Bug melden.

Die von der Schnittstelle Node vererbte Eigenschaft nextSibling gibt allgemein den Knoten zurück, der den selben Elternknoten hat wie der Knoten über den die Eigenschaft referenziert wird und der diesem in Richtung des Baums nachfolgt, oder den Wert null, wenn das Kontextobjekt der letzte Kindknoten seines Vorfahren ist.

Beachte, dass es hier allgemein um Knoten geht und nicht speziell um Elemente, die eine besondere Form von Knoten darstellen, welche durch die Schnittstelle Element repräsentiert wird. Da es sich bei Elementen um Knoten handelt, erben sie neben den Eigenschaften und Methoden von Element auch jene von der Schnittstelle Node. Wie eben die genannte Eigenschaft nextSibling.

Node → Element

Außer Elementen gibt es jedoch noch einige andere Knotentypen, wie beispielsweise Textknoten, welche durch die Schnittstelle Text repräsentiert werden. Diese Knoten erben auf dem Umweg über die Schnittstelle CharacterData ebenfalls die Eigenschaften und Methoden von Node.

Node → CharacterData → Text

Das heißt, die auf Node definierten Eigenschaften und Methoden wie nextSibling stellen sozusagen die Grundausstattung für alle Knoten innerhalb des Document Object Models dar, unabhängig von ihrem genauen Typ. Spezifischere Schnittstellen wie Element oder Text erweitern dann diese Grundfunktionalität um weitere Eigenschaften und Methoden.

Das oben gesagte kann übrigens leicht nachgeprüft werden, da zumindest die gennanten, abstrakt definierten Schnittstellen des Document Object Models im Browser als globale Objekte direkt referenziert werden können, so wie in dem folgenden Beispiel.

console.info(document.body instanceof Element && document.body instanceof Node); // true

Auch kann man sich vergewissern, dass es sich bei nextSibling tatsächlich um eine von Node vererbte Eigenschaft handelt, auch wenn sie wie in deinem Beispiel über ein Element referenziert wird.

console.info(Node.prototype.hasOwnProperty('nextSibling')); // true

Diese Eigenschaft ist als Getter implementiert, dessen Kontextvariable this mit dem Objekt initialisiert wird, über das die Eigenschaft angesprochen wurde. Es handelt sich also tatsächlich um keine eigene Eigenschaft der einzelnen durch Objekte repräsentierten Knoten des Baums.

console.info(document.body.hasOwnProperty('nextSibling')); // false

Jedenfalls, weil es sich um eine auf der Schnittstelle Node angesiedelte Eigenschaft handelt, sind aus Sicht von nextSibling alle Objekte einfach nur Knoten. Das heißt, wenn wie hier im Quelltext auf das Kontextobjekt Whitespace folgt, dann wird dieser zu einem Textknoten geparst, und da es sich dabei um einen Knoten handelt, wird dieser von der Eigenschaft nextSibling referenziert.

Das ist aber natürlich nicht das, was eigentlich gewünscht ist, denn eigentlich soll ja das nächste Geschwisterelement referenziert werden und kein Textknoten. Dementsprechend ist nextSibling hier von vorneherein die falsche Wahl gewesen.

Besser wäre es gewesen, die Eigenschaft nextElementSibling zu verwenden, die sowohl von der Schnittstelle Element als auch von der Schnittstelle CharacterData implementiert wird, und somit auf Element- und Textknoten angesprochen werden kann. Diese Eigenschaft referenziert nicht allgemein den nächsten Geschwisterknoten, sondern das nächste Geschwisterelement.

Es gibt auch für andere Eigenschaften der Schnittstelle Node Entsprechungen, bei denen nicht allgemein Knoten, sondern ausschließlich Elemente referenziert werden. Zum Beispiel gibt es neben previousSibling auch die Eigenschaft previousElementSibling, welche das vorangehende Geschwisterelement enthält, für den Fall, dass ein solches vorhanden ist.

Darüber hinaus können statt der von Node vererbten Eigenschaften firstChild und lastChild die Eigenschaften firstElementChild und lastElementChild angesprochen werden, die im Gegensatz zu den erstgenannten Eigenschaften ausschließlich Elemente referenzieren.

Die von Node vererbte Eigenschaft childNodes gibt eine NodeList mit Kindknoten zurück, also auch mit Textknoten. Die unter anderem von Elementen implementierte Eigenschaft children hingegen gibt eine HTMLCollection zurück, die nur Elementknoten enthält.

Wenn man also schon Elemente über Eigenschaften referenzieren möchte, und nicht auf Methoden wie beispielsweise querySelector zurückgreifen will, was meist die bessere Wahl ist, dann ist es hilfreich zu wissen, welchem Zweck die jeweiligen Eigenschaften dienen.

Viele Grüße,

Orlok