nextElementSibling, previousElementSibling: direkte Nachbar-Elemente
previousElementSibling und nextElementSilbling greifen auf benachbarte Elemente desselben Elternknotens zu, die nicht direkt durch eine CSS-Klasse oder -id, also über Methoden wie getElementById, getElementsByName oder querySelector erreicht werden.
Nachbar-Elemente direkt ansprechen
Auf benachbarte Elemente greift das Script meist über CSS-Selektoren wie querySelector oder getElementById zu. Das ist komfortabel und sicher – auch wenn sich das HTML-Markup ändert. Aber wenn CSS-Klassen und IDs für die Zuordnung nicht verfügbar sind?
nextElementSibling und previousElementSibling sind schnell und direkt, da sie nur einen Schritt im DOM gehen.
<figure> <img src="figur1.jpg" width="360" height="360" alt="Oder (Ziege und Fell)"> <figcaption></figcaption> </figure>
Den Text für das figcaption-Element aus dem alt-Attribut des vorangehenden img-Elements lesen und einsetzen.
function createFigcaption ( item ) {
if (item.nextElementSibling && item.nextElementSibling.nodeName === "FIGCAPTION") {
item.nextElementSibling.innerHTML = item.getAttribute("alt");
}
}
const flüße = document.querySelectorAll (".neptun img");
flüße.forEach ((item) => createFigcaption( item ));
Wenn kein Nachfolger bzw. Vorgänger auf derselben Ebene existiert, geben previousElementSibling und nextElementSibling null zurück.
previousElementSibling
Hier wird Javascript gebraucht, denn CSS ist abwärts gerichtet: CSS erreicht Elemente, die nach einem Referenzelement liegen – z.B. ein p-Element, das direkt auf ein h2 folgt oder Menü-Elemente, die nach einem input-Element sitzen –, aber an die Vorgänger derselben Ebene kommt CSS nicht.
- Bunte Kleider
- Lässige Kleider
- Elegante Kleider
- Strandkleider
ol ist eine geordnete Liste in einem ol-Element, das weder über eine CSS-Klasse noch eine ID erreicht wird.
<ol> <li>Bunte Kleider</li> <li>Lässige Kleider</li> <li>Elegante Kleider</li> <li>Strandkleider</li> </ol> <button id="btnTurn">Reihenfolge umkehren</button>
const turn = document.getElementById("btnTurn");
turn.addEventListener ("click", function () {
let lastChild = this.previousElementSibling.lastElementChild;
const result = document.createElement("DIV");
while (lastChild) {
result.innerHTML += lastChild.outerHTML;
lastChild = lastChild.previousElementSibling;
}
turn.previousElementSibling.innerHTML = result.innerHTML;
});
Accordion mit nextElementSibling
<div class="accordion"> <div> <button class="btn Liquorice"><b>❦</b> Liquorice</button> <ul class="panel"> <li>Liquorice wafer lollipop sesame</li> <li>…</li> </ul> </div> <div> <button class="btn Cheesecake"><b>❁</b> Cheesecake?</button> <ul class="panel"> <li>…</li> <li>…</li> </ul> </div> … </div>
ul class="panel" ist nur ein Element weit vom auslösenden Button entfernt. Das macht den Zugriff über nextElementSibling einfach und effizient.
- Liquorice wafer lollipop sesame
- snaps gummi bears. Wafer jelly beans chupa chups cotton candy
- caramels carrot cake topping oat cake.
- Cake carrot cake marshmallow cheesecake cake lemon drops pudding apple pie.
- Chocolate gingerbread marshmallow croissant.
- Liquorice jujubes cake ice cream cake liquorice croissant ice cream.
- Lollipop jelly-o fruitcake chocolate cake tootsie roll marzipan dragée halvah.
- Chocolate gingerbread marshmallow croissant.
- Liquorice jujubes cake ice cream cake liquorice croissant ice cream.
Fruitcake marshmallow sugar plum soufflé biscuit.
Sesame snaps pie lemon drops.
const button = document.querySelectorAll("button.btn");
button.forEach(item => {
item.addEventListener('click', e => {
button.forEach (elem => {
elem.nextElementSibling.classList.remove("open");
})
e.target.nextElementSibling.classList.add('open');
});
});
previousSibling und nextSilbling: alte DOM-Eigenschaften
previousSibling und nextSilbling waren die Vorläufer für previousElementSibling und nextElementSibling aus der Frühzeit des DOM, die nicht nur Element-Knoten, sondern auch Leerzeichen, Kommentare und Zeilenumbrüche als Nachbarn anerkennen.
Diese älteren Eigenschaften interpretierten auch das Füllmaterial (Kommentare, Zeilenumbrüche und Leerzeichen) im HTML-Markup als Kind- oder Nachbarknoten.
<div class="statuen">
<figure>
<img src="statue.jpg" width="480" height="647" alt="statue-berlin-480">
<figcaption>Berlin</figcaption>
</figure>
…
</div>
Um bei einem Klick auf ein Bild an den Text im figcaption-Element zu kommen, müsste nextSibling einen Zeilenbruch und ein paar Tabs überbrücken, vielleicht aber auch Leerzeichen anstelle von Tabs, und am Ende prüfen, ob es das gesuchte figcaption-Element überhaupt gibt.
let search = true;
let a = 0;
while (elem.nextSibling && search) {
if (elem.nextSibling.nodeType === 1 && elem.nextSibling.nodeName === "FIGCAPTION") {
caption = elem.nextSibling.innerHTML;
search = false;
} else {
elem = elem.nextSibling;
}
a = a + 1;
}
if (search === true) {
console.log ("keine Unterschrift zu Bild a " + (a +1));
}
Der Einsatz von previousSibling und nextSilbling lohnt nur, wenn tatsächlich auch leere Knoten aus dem HTML-Markup eine Rolle spielen.