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

Range.setStartAfter()

Methode

Setzt den Startpunkt eines <code>Range</code> direkt hinter den angegebenen Knoten – also in dessen Elternknoten, unmittelbar nach ihm.

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

Signatur

Range.prototype.setStartAfter(referenceNode)

Beschreibung

setStartAfter() verschiebt den Startpunkt eines Range-Objekts an die Stelle direkt nach dem übergebenen Knoten. Intern entspricht das range.setStart(referenceNode.parentNode, index + 1), wobei index die Position des Knotens unter den Kindern seines Elternknotens ist. Du musst den Index also nicht selbst ermitteln.

Nützlich ist die Methode, wenn ein Bereich hinter einem bestimmten Element beginnen soll, etwa um alle Geschwister nach einer Überschrift auszuwählen, Inhalte hinter einem Marker-Element zu löschen oder den Cursor in einem contenteditable-Bereich hinter ein gerade eingefügtes Element zu setzen.

Liegt der neue Startpunkt hinter dem aktuellen Endpunkt (oder in einem anderen Dokument bzw. Baum), wird der Range auf den neuen Startpunkt zusammengeklappt (collapsed === true), d. h. auch der Endpunkt wird dorthin verschoben.

Parameter

Name Typ Default Beschreibung
$referenceNode Pflicht Node Knoten, hinter dem der Range beginnen soll. Muss einen Elternknoten besitzen.

Beispiele

Alle Absätze nach einer Überschrift auswählen

// HTML: <article><h2 id="titel">Titel</h2><p>Eins</p><p>Zwei</p></article>
const titel = document.getElementById('titel');
const range = document.createRange();

range.setStartAfter(titel);                 // Start direkt hinter <h2>
range.setEndAfter(titel.parentNode.lastChild); // Ende hinter dem letzten Kind

console.log(range.toString());
console.log(range.startContainer.tagName, range.startOffset);
EinsZwei ARTICLE 1

Inhalt hinter einem Marker entfernen

// HTML: <ul id="liste"><li>A</li><li id="marker">B</li><li>C</li><li>D</li></ul>
const marker = document.getElementById('marker');
const liste = document.getElementById('liste');

const range = document.createRange();
range.setStartAfter(marker);
range.setEnd(liste, liste.childNodes.length);
range.deleteContents();

console.log(liste.textContent);
AB

Cursor hinter eingefügtes Element setzen (contenteditable)

const insertEmoji = (emoji) => {
  const selection = window.getSelection();
  if (!selection.rangeCount) return;

  const range = selection.getRangeAt(0);
  const span = document.createElement('span');
  span.textContent = emoji;

  range.deleteContents();
  range.insertNode(span);

  // Cursor hinter das neue <span> setzen
  range.setStartAfter(span);
  range.collapse(true);
  selection.removeAllRanges();
  selection.addRange(range);
};

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

Automatisches Zusammenklappen

const range = document.createRange();
const p = document.createElement('p');
p.innerHTML = '<b>1</b><i>2</i>';

range.selectNode(p.firstChild);   // Range umfasst <b>
range.setStartAfter(p.lastChild); // Start liegt hinter dem Ende

console.log(range.collapsed, range.startOffset, range.endOffset);
true 2 2

// Wichtig · Fallstricke

  • Kein Elternknoten: Hat referenceNode keinen parentNode (z. B. ein losgelöstes Element oder das document selbst), wird eine DOMException vom Typ InvalidNodeTypeError ausgelöst.
  • Doctype: Auch ein DocumentType-Knoten als Elternknoten führt zu einem InvalidNodeTypeError.
  • Zusammenklappen: Liegt der neue Start hinter dem aktuellen Ende, wird auch das Ende verschoben – bei Bedarf danach mit setEnd()/setEndAfter() neu setzen.
  • Offsets: Der Startcontainer ist danach immer der Elternknoten, nicht der Referenzknoten selbst. Bei Textknoten als Ziel für zeichengenaue Positionen stattdessen setStart(textNode, offset) verwenden.
  • Live-Verhalten: Ranges passen sich bei späteren DOM-Änderungen automatisch an; ein StaticRange tut das nicht.
  • Wird von allen modernen Browsern unterstützt.