Start · Sprachen · JavaScript · Referenz · Node.insertBefore()

Node.insertBefore()

Methode

Fügt <code>newNode</code> als Kind des aufrufenden Elternknotens direkt vor <code>referenceNode</code> ein. Ist <code>referenceNode</code> gleich <code>null</code>, landet er am Ende.

seit JavaScript Baseline: alle Browser (DOM Level 1) Kategorie: webapi

Signatur

Node.prototype.insertBefore(newNode, referenceNode)

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

Typ
Node
Beschreibung
Der eingefügte Knoten, also 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));
["Dringend: Steuer", "Einkaufen", "Sport"]

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);
true

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);
ACB

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: referenceNode muss ein direktes Kind des Elternknotens sein, sonst wirft sie eine DOMException vom Typ NotFoundError.
  • 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 einen HierarchyRequestError.
  • Das zweite Argument nie weglassen: Gib bei Bedarf ausdrücklich null an. Ohne Argument werfen die meisten Browser einen TypeError.
  • Leerzeichen-Textknoten: firstChild und nextSibling liefern auch Textknoten mit Leerzeichen und Zeilenumbrüchen aus dem HTML-Quelltext. Wenn es dir nur um Elemente geht, nimm firstElementChild bzw. nextElementSibling. Diese sind bei fehlendem Element ebenfalls null.
  • 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 Browsern moveBefore().
  • Sicherheit: Füllst du Knoten mit Inhalten von Nutzern, verwende textContent statt innerHTML, sonst droht XSS.
  • Kompatibilität: Wird von allen Browsern unterstützt, auch von sehr alten. Die moderneren Alternativen before(), after() und prepend() gibt es seit etwa 2018 in allen aktuellen Browsern.