Signatur
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
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());
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}`);
});
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);
});
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);
// Wichtig · Fallstricke
- Nur lesbar: Eine Zuweisung an
range.startContainer = …bleibt ohne Wirkung und wirft im Strict Mode einenTypeError. Nehmen Sie stattdessenRange.setStart()odersetStartBefore()/setStartAfter(). - Offset richtig deuten: Bei Textknoten zählt
startOffsetUTF-16-Codeeinheiten, sonst Kindknoten. Emojis und andere Zeichen außerhalb der BMP belegen zwei Einheiten. - Textknoten statt Element: In der Praxis ist
startContaineroft einText-Knoten. Methoden wieclosest()oderclassListgibt es dort nicht, daher vorherparentElementverwenden. - StaticRange wird nicht aktualisiert: Ändert sich das DOM, passt ein
Rangeseine Grenzpunkte automatisch an, einStaticRangedagegen nicht. DessenstartContainerkann 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 esSelection.getComposedRanges()als neuere Alternative. - Kompatibilität:
Range.startContainerwird von allen Browsern schon lange unterstützt. Die gemeinsame BasisschnittstelleAbstractRangeundStaticRangegibt es in aktuellen Versionen von Chrome, Firefox, Safari und Edge.