Start · Sprachen · JavaScript · Referenz · Range.insertNode()

Range.insertNode()

Methode

Fügt einen Knoten am Anfang des <code>Range</code> ein und teilt dabei bei Bedarf einen Textknoten an der Startposition.

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

Signatur

Range.prototype.insertNode(newNode)

Beschreibung

Range.insertNode() fügt den übergebenen Knoten an der Startposition eines Range in das Dokument ein. Liegt der Startpunkt mitten in einem Text-Knoten, wird dieser an der Stelle aufgeteilt (wie bei Text.splitText()) und der neue Knoten zwischen die beiden Teile gesetzt. Beginnt der Range in einem Element, wird der Knoten vor dem Kindknoten am Index startOffset eingefügt.

Typische Anwendungsfälle sind Rich-Text-Editoren, das Einfügen von Markierungen, Emojis oder Platzhaltern an der Cursorposition (über window.getSelection().getRangeAt(0)) sowie das gezielte Einfügen von Inhalten an einer berechneten Textstelle.

Ist newNode ein DocumentFragment, werden stattdessen dessen Kinder eingefügt und das Fragment danach geleert. Ein bereits im Dokument vorhandener Knoten wird verschoben, nicht kopiert. Nach dem Einfügen ist der Range (sofern er zuvor kollabiert war) so erweitert, dass er den neuen Knoten umschließt; bei nicht kollabierten Ranges bleibt das Ende unverändert und der Inhalt wird nicht ersetzt – dafür vorher deleteContents() aufrufen.

Parameter

Name Typ Default Beschreibung
$newNode Pflicht Node Der einzufügende Knoten, z. B. ein Element, Text oder DocumentFragment. Vorhandene Knoten werden an die neue Position verschoben.

Beispiele

Element an einer Textstelle einfügen

// <p id="text">Hallo Welt</p>
const textNode = document.getElementById('text').firstChild;
const range = document.createRange();
range.setStart(textNode, 5); // nach "Hallo"
range.collapse(true);

const strong = document.createElement('strong');
strong.textContent = ' schöne';
range.insertNode(strong);

console.log(document.getElementById('text').innerHTML);
Hallo<strong> schöne</strong> Welt

Inhalt an der Cursorposition einfügen (Editor)

// <div contenteditable id="editor">...</div>
const insertAtCursor = (text) => {
  const selection = window.getSelection();
  if (!selection.rangeCount) return;

  const range = selection.getRangeAt(0);
  range.deleteContents(); // markierten Text ersetzen

  const node = document.createTextNode(text);
  range.insertNode(node);

  // Cursor hinter den eingefügten Text setzen
  range.setStartAfter(node);
  range.collapse(true);
  selection.removeAllRanges();
  selection.addRange(range);
};

document.querySelector('#emoji-btn')
  .addEventListener('click', () => insertAtCursor('😀'));

Mehrere Knoten per DocumentFragment einfügen

const list = document.querySelector('ul');
const range = document.createRange();
range.setStart(list, 0); // vor das erste Kind

const fragment = document.createDocumentFragment();
['Neu 1', 'Neu 2'].forEach((label) => {
  const li = document.createElement('li');
  li.textContent = label;
  fragment.append(li);
});

range.insertNode(fragment);
console.log(fragment.childNodes.length); // Fragment ist nun leer

// Wichtig · Fallstricke

  • Ersetzt nichts: Bei einer Markierung wird der Knoten nur am Anfang eingefügt – der markierte Inhalt bleibt erhalten. Zum Ersetzen zuerst range.deleteContents() aufrufen.
  • Textknoten werden geteilt: Liegt der Start in einem Text-Knoten, entstehen zwei Textknoten. Mit element.normalize() lassen sich benachbarte Textknoten später wieder zusammenführen.
  • Ausnahmen: HierarchyRequestError, wenn der Start in einem Comment- oder ProcessingInstruction-Knoten liegt, der Knoten ein Vorfahre des Startcontainers ist oder die Einfügung ungültig wäre (z. B. ein Document).
  • Cursorposition: Nach dem Einfügen umschließt ein zuvor kollabierter Range den neuen Knoten. Für eine natürliche Cursorposition den Range mit setStartAfter() + collapse(true) anpassen.
  • Sicherheit: Knoten per createElement/createTextNode erzeugen statt HTML-Strings mit createContextualFragment() aus Benutzereingaben zu parsen – sonst XSS-Gefahr.
  • Seit Jahren in allen gängigen Browsern unterstützt.