Signatur
Beschreibung
Die schreibgeschützte Eigenschaft previousElementSibling gibt es an allen CharacterData-Knoten, also an Text, Comment, CDATASection und ProcessingInstruction. Sie läuft von diesem Knoten aus in der Kindliste des Elternknotens rückwärts und liefert das erste Element, auf das sie trifft. Text- und Kommentarknoten dazwischen werden übersprungen.
Das ist vor allem nützlich, wenn man beim Durchlaufen des DOM auf einem Textknoten gelandet ist, etwa über einen TreeWalker, eine Range, die Auswahl (Selection.anchorNode) oder einen MutationObserver, und das benachbarte Element davor braucht. Anders als previousSibling muss man dafür keine Leerzeichen-Textknoten von Hand herausfiltern.
Die Eigenschaft stammt aus dem Mixin NonDocumentTypeChildNode, das auch Element einbindet. Sie verhält sich deshalb genauso wie Element.previousElementSibling. Gibt es keinen Elternknoten oder vor dem Knoten kein Element mehr, ist der Wert null.
Rückgabewert
Element oder null, wenn es keines gibt oder der Knoten keinen Elternknoten hat.Beispiele
Element vor einem Textknoten finden
const p = document.createElement('p');
p.innerHTML = '<strong>Hinweis:</strong> <!-- Kommentar --> Bitte speichern.';
// Letzter Kindknoten ist der Textknoten " Bitte speichern."
const text = p.lastChild;
console.log(text.nodeType === Node.TEXT_NODE);
console.log(text.previousSibling.nodeName); // Leerzeichen-Textknoten
console.log(text.previousElementSibling.tagName); // Kommentar und Leerzeichen werden übersprungen
Kommentar-Marker: vorangehendes Element ermitteln
const list = document.createElement('ul');
list.innerHTML = '<li>Eins</li><li>Zwei</li><!-- marker --><li>Drei</li>';
const marker = [...list.childNodes].find(
(n) => n.nodeType === Node.COMMENT_NODE && n.data.trim() === 'marker'
);
console.log(marker.previousElementSibling.textContent);
console.log(marker.nextElementSibling.textContent);
Kein Element davor bzw. kein Elternknoten
const div = document.createElement('div');
div.append('Nur Text', document.createElement('span'));
console.log(div.firstChild.previousElementSibling); // nichts davor
const lose = document.createTextNode('ohne Eltern');
console.log(lose.previousElementSibling); // kein Elternknoten
Praxis: Überschrift zum ausgewählten Text finden
document.addEventListener('mouseup', () => {
const node = window.getSelection()?.anchorNode;
if (!node || node.nodeType !== Node.TEXT_NODE) return;
// Rückwärts über Elemente laufen, bis eine Überschrift kommt
let el = node.previousElementSibling;
while (el && !/^H[1-6]$/.test(el.tagName)) {
el = el.previousElementSibling;
}
console.log('Abschnitt:', el?.textContent ?? '(keine Überschrift auf gleicher Ebene)');
});
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung wird still ignoriert und löst im Strict Mode keinen Fehler aus. Zum Verschieben von Knoten nimmt man
before(),after()oderinsertBefore(). - Nicht mit
previousSiblingverwechseln:previousSiblingliefert jeden Knotentyp, auch Leerzeichen-Textknoten aus der HTML-Formatierung.previousElementSiblingliefert nur Elemente. - Nur Geschwister: Die Eigenschaft bleibt auf der Ebene des Elternknotens. Für das umschließende Element nimmt man
parentElement, für Vorfahrenclosest()am Elternelement. - Die Eigenschaft gibt es nicht an
Document,DocumentFragmentundDocumentType. - Kompatibilität: Alle modernen Browser unterstützen sie. Der alte Internet Explorer kannte
previousElementSiblingnur an Elementen, nicht an Text- oder Kommentarknoten. Dort lief man mitpreviousSiblingund einer Prüfung aufnodeType === 1rückwärts. - Der Wert wird bei jedem Zugriff frisch ausgewertet. Nach DOM-Änderungen ist er also immer aktuell, man sollte ihn aber nicht über Mutationen hinweg zwischenspeichern.