Start · Sprachen · JavaScript · Referenz · AbstractRange.startContainer

AbstractRange.startContainer

Eigenschaft

Schreibgeschützte Eigenschaft, die den <code>Node</code> liefert, in dem der Bereich (<code>Range</code> oder <code>StaticRange</code>) beginnt.

seit JavaScript Baseline: alle Browser (AbstractRange als gemeinsa Kategorie: webapi

Signatur

get AbstractRange.startContainer

Beschreibung

startContainer ist eine schreibgeschützte Eigenschaft der abstrakten Schnittstelle AbstractRange. Damit erben sowohl Range als auch StaticRange diese Eigenschaft. Sie gibt den Knoten zurück, in dem der Anfangspunkt des Bereichs liegt. Zusammen mit startOffset bestimmt sie die genaue Startposition.

Was startOffset bedeutet, hängt vom Knotentyp ab: Ist startContainer ein Text-, Comment- oder CDATASection-Knoten, zählt der Offset Zeichen (genauer: UTF-16-Codeeinheiten). Bei allen anderen Knoten, etwa einem Element oder einem Document, zählt der Offset Kindknoten.

Gebraucht wird die Eigenschaft vor allem bei Rich-Text-Editoren, beim Auswerten einer Benutzerauswahl über Selection.getRangeAt(), bei Hervorhebungen (z. B. mit der CSS Custom Highlight API) und bei beforeinput-Events, deren getTargetRanges() StaticRange-Objekte liefert. Ändern lässt sich der Startpunkt nur bei einem Range, und zwar über Methoden wie setStart(), setStartBefore() oder selectNode(), nicht durch Zuweisen an die Eigenschaft.

Rückgabewert

Typ
Node
Beschreibung
Der Knoten, in dem der Bereich beginnt. Häufig ist das ein Text-Knoten, es kann aber auch ein Element, Document, DocumentFragment oder Comment sein. Bei einem frisch erzeugten Range ist es das document, in dem er erstellt wurde.

Beispiele

Startknoten eines selbst gesetzten Range auslesen

const p = document.createElement('p');
p.textContent = 'Hallo Welt';
document.body.append(p);

const range = document.createRange();
console.log(range.startContainer === document); // Standard: Dokument

// Bereich beginnt beim 6. Zeichen des Textknotens
range.setStart(p.firstChild, 6);
range.setEnd(p.firstChild, 10);

console.log(range.startContainer.nodeName);
console.log(range.startOffset);
console.log(range.toString());
true #text 6 Welt

Benutzerauswahl analysieren

document.addEventListener('mouseup', () => {
  const selection = window.getSelection();
  if (!selection || selection.rangeCount === 0) return;

  const range = selection.getRangeAt(0);
  const { startContainer, startOffset } = range;

  // Elternelement bestimmen, auch wenn der Start in einem Textknoten liegt
  const startElement = startContainer.nodeType === Node.TEXT_NODE
    ? startContainer.parentElement
    : startContainer;

  console.log(`Auswahl beginnt in <${startElement?.tagName.toLowerCase()}> bei Offset ${startOffset}`);
});
Auswahl beginnt in <p> bei Offset 3

StaticRange aus beforeinput auswerten

const editor = document.querySelector('[contenteditable]');

editor.addEventListener('beforeinput', (event) => {
  const [target] = event.getTargetRanges(); // StaticRange[]
  if (!target) return;

  console.log(event.inputType, '→ Start in', target.startContainer.nodeName, 'bei', target.startOffset);
});
insertText → Start in #text bei 5

Offset abhängig vom Knotentyp interpretieren

const list = document.createElement('ul');
list.innerHTML = '<li>A</li><li>B</li><li>C</li>';

const range = document.createRange();
range.setStart(list, 1); // Offset zählt hier Kindknoten
range.setEnd(list, 3);

const { startContainer, startOffset } = range;
const startNode = startContainer.childNodes[startOffset];
console.log(startContainer.nodeName, startNode.textContent);
UL B

// Wichtig · Fallstricke

  • Nur lesbar: Eine Zuweisung an range.startContainer = … bleibt ohne Wirkung und wirft im Strict Mode einen TypeError. Nehmen Sie stattdessen Range.setStart() oder setStartBefore()/setStartAfter().
  • Offset richtig deuten: Bei Textknoten zählt startOffset UTF-16-Codeeinheiten, sonst Kindknoten. Emojis und andere Zeichen außerhalb der BMP belegen zwei Einheiten.
  • Textknoten statt Element: In der Praxis ist startContainer oft ein Text-Knoten. Methoden wie closest() oder classList gibt es dort nicht, daher vorher parentElement verwenden.
  • StaticRange wird nicht aktualisiert: Ändert sich das DOM, passt ein Range seine Grenzpunkte automatisch an, ein StaticRange dagegen nicht. Dessen startContainer kann dann auf einen entfernten Knoten zeigen, und der Offset kann ungültig sein.
  • Shadow DOM: Bei Selection.getRangeAt() kann der Startknoten je nach Browser abweichen, wenn die Auswahl Grenzen von Shadow Roots überschreitet. Hier gibt es Selection.getComposedRanges() als neuere Alternative.
  • Kompatibilität: Range.startContainer wird von allen Browsern schon lange unterstützt. Die gemeinsame Basisschnittstelle AbstractRange und StaticRange gibt es in aktuellen Versionen von Chrome, Firefox, Safari und Edge.