Signatur
Beschreibung
insertBefore() wird auf dem Elternknoten aufgerufen und fügt einen Knoten an einer bestimmten Stelle zwischen dessen Kindern ein, nämlich direkt vor dem angegebenen Referenzknoten. Damit lassen sich Elemente gezielt positionieren, etwa ein neuer Listeneintrag ganz oben, ein Hinweis vor einem Formularfeld oder ein Element, das beim Sortieren an eine neue Stelle kommt.
Ist referenceNode gleich null, verhält sich die Methode wie appendChild() und hängt den Knoten als letztes Kind an. Hängt newNode schon irgendwo im Dokument, wird er dabei verschoben und nicht kopiert, denn ein Knoten kann nur an einer Stelle im Baum stehen. Brauchst du eine Kopie, rufe vorher cloneNode() auf.
Übergibst du ein DocumentFragment, werden alle seine Kinder in ihrer Reihenfolge eingefügt, und das Fragment ist danach leer. So fügst du viele Knoten mit nur einem Zugriff auf den DOM-Baum ein.
Eine Methode insertAfter() gibt es nicht. Den gleichen Effekt erreichst du mit parent.insertBefore(newNode, referenceNode.nextSibling). Ist nextSibling gleich null, wird am Ende eingefügt. Die neueren Methoden before(), after() und prepend() sind oft kürzer und nehmen auch Zeichenketten an.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $newNode Pflicht | Node | Der einzufügende Knoten, z. B. ein Element, ein Text-Knoten oder ein DocumentFragment. Hängt er schon im Dokument, wird er verschoben. |
|
| $referenceNode Pflicht | Node | null | Das Kind des Elternknotens, vor dem eingefügt wird. Bei null wird am Ende eingefügt. Das Argument muss ausdrücklich angegeben werden, undefined wird nicht zuverlässig wie null behandelt. |
Rückgabewert
newNode. Bei einem DocumentFragment ist das das nun leere Fragment.Beispiele
Neuen Eintrag am Anfang einer Liste einfügen
// <ul id="todos"><li>Einkaufen</li><li>Sport</li></ul>
const list = document.querySelector('#todos');
const item = document.createElement('li');
item.textContent = 'Dringend: Steuer';
// firstChild ist bei leerer Liste null, dann wird angehängt
list.insertBefore(item, list.firstChild);
console.log([...list.children].map((li) => li.textContent));
insertAfter-Hilfsfunktion mit nextSibling
const insertAfter = (newNode, referenceNode) =>
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
// Fehlermeldung direkt hinter einem Eingabefeld anzeigen
const input = document.querySelector('#email');
const error = document.createElement('span');
error.className = 'error';
error.textContent = 'Bitte gültige E-Mail angeben';
insertAfter(error, input);
console.log(input.nextElementSibling === error);
Vorhandenes Element verschieben (Sortieren nach oben)
// <ol id="ranking"><li>A</li><li>B</li><li>C</li></ol>
const ranking = document.querySelector('#ranking');
const moveUp = (li) => {
const prev = li.previousElementSibling;
if (prev) ranking.insertBefore(li, prev); // verschiebt, kopiert nicht
};
moveUp(ranking.children[2]);
console.log(ranking.textContent);
Viele Knoten mit einem DocumentFragment einfügen
const table = document.querySelector('tbody');
const fragment = document.createDocumentFragment();
['Anna', 'Ben', 'Clara'].forEach((name) => {
const row = document.createElement('tr');
row.innerHTML = '<td></td>';
row.firstChild.textContent = name; // sicher gegen XSS
fragment.appendChild(row);
});
// Alle Zeilen vor der ersten vorhandenen Zeile einfügen
const result = table.insertBefore(fragment, table.firstElementChild);
console.log(result.childNodes.length); // Fragment ist danach leer
// Wichtig · Fallstricke
- Die Methode wird auf dem Elternknoten aufgerufen:
referenceNodemuss ein direktes Kind des Elternknotens sein, sonst wirft sie eineDOMExceptionvom TypNotFoundError. - Ungültige Hierarchie: Willst du einen Vorfahren in einen seiner eigenen Nachkommen einfügen oder einen Knotentyp an eine nicht erlaubte Stelle setzen (z. B. ein zweites Wurzelelement in
document), wirft die Methode einenHierarchyRequestError. - Das zweite Argument nie weglassen: Gib bei Bedarf ausdrücklich
nullan. Ohne Argument werfen die meisten Browser einenTypeError. - Leerzeichen-Textknoten:
firstChildundnextSiblingliefern auch Textknoten mit Leerzeichen und Zeilenumbrüchen aus dem HTML-Quelltext. Wenn es dir nur um Elemente geht, nimmfirstElementChildbzw.nextElementSibling. Diese sind bei fehlendem Element ebenfallsnull. - Verschieben statt Kopieren: Ein Knoten, der schon im Dokument hängt, wird aus seiner alten Position entfernt. Event-Listener bleiben dabei erhalten, der Zustand von
<iframe>-Elementen wird dagegen beim Verschieben neu geladen. Für ein echtes Verschieben ohne Neuladen gibt es in neueren BrowsernmoveBefore(). - Sicherheit: Füllst du Knoten mit Inhalten von Nutzern, verwende
textContentstattinnerHTML, sonst droht XSS. - Kompatibilität: Wird von allen Browsern unterstützt, auch von sehr alten. Die moderneren Alternativen
before(),after()undprepend()gibt es seit etwa 2018 in allen aktuellen Browsern.