Start · Sprachen · JavaScript · Referenz · AbstractRange.startOffset

AbstractRange.startOffset

Eigenschaft

Gibt den Versatz innerhalb von <code>startContainer</code> zurück, an dem ein <code>Range</code> oder <code>StaticRange</code> beginnt. Die Eigenschaft ist schreibgeschützt.

seit JavaScript Baseline: alle modernen Browser (seit 2021) Kategorie: webapi

Signatur

AbstractRange.startOffset

Beschreibung

Die schreibgeschützte Eigenschaft startOffset gibt zusammen mit startContainer die genaue Startposition eines Bereichs im DOM an. AbstractRange ist die gemeinsame Basis von Range und StaticRange, deshalb steht die Eigenschaft bei beiden zur Verfügung.

Was der Wert bedeutet, hängt vom Knotentyp des startContainer ab:

  • Bei Text-, Comment- und CDATASection-Knoten ist es die Anzahl der Zeichen, genauer der UTF-16-Codeeinheiten, vom Anfang des Knotens bis zum Startpunkt.
  • Bei allen anderen Knoten, zum Beispiel Element oder Document, ist es der Index des Kindknotens, vor dem der Bereich beginnt. 0 steht also für „vor dem ersten Kind“.

Typische Einsatzfälle sind Texteditoren, das Auswerten einer Benutzerauswahl (Selection.getRangeAt()), Hervorhebungen und Anmerkungen sowie die Auswertung von InputEvent.getTargetRanges(). Ändern lässt sich die Startposition nur bei einem Range, und zwar mit setStart() oder ähnlichen Methoden. Eine direkte Zuweisung an startOffset ist nicht möglich.

Rückgabewert

Typ
number
Beschreibung
Eine nicht-negative ganze Zahl. Bei Zeichendaten-Knoten ist es ein Zeichen-Versatz (UTF-16-Codeeinheiten), bei allen anderen Knoten ein Index in childNodes.

Beispiele

Zeichen-Versatz in einem Textknoten

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

const range = document.createRange();
// Start nach "Hallo " im Textknoten
range.setStart(p.firstChild, 6);
range.setEnd(p.firstChild, 10);

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

Kindindex bei einem Element-Container

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

const range = document.createRange();
// Bereich beginnt vor dem zweiten <li>
range.setStart(ul, 1);
range.setEnd(ul, 3);

console.log(range.startOffset);
console.log(ul.childNodes[range.startOffset].textContent);
1 B

Cursorposition aus der Benutzerauswahl lesen

document.addEventListener('selectionchange', () => {
  const sel = document.getSelection();
  if (!sel || sel.rangeCount === 0) return;

  const { startContainer, startOffset } = sel.getRangeAt(0);
  if (startContainer.nodeType === Node.TEXT_NODE) {
    const vorher = startContainer.data.slice(0, startOffset);
    console.log(`Cursor nach ${startOffset} Zeichen: "${vorher}"`);
  }
});
Cursor nach 5 Zeichen: "Hallo"

StaticRange bei beforeinput auswerten

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

editor.addEventListener('beforeinput', (event) => {
  for (const r of event.getTargetRanges()) {
    // r ist ein StaticRange, erbt startOffset von AbstractRange
    console.log(event.inputType, r.startOffset, r.endOffset);
  }
});
deleteContentBackward 4 5

// Wichtig · Fallstricke

  • Die Bedeutung hängt vom Knotentyp ab: Prüfe immer den nodeType von startContainer, bevor du startOffset als Zeichenposition oder als Kindindex auswertest.
  • UTF-16: Bei Emojis und anderen Zeichen außerhalb der BMP zählt ein sichtbares Zeichen als zwei Einheiten. Der Versatz entspricht daher nicht unbedingt der Anzahl der sichtbaren Zeichen.
  • Live oder statisch: Bei einem Range passt der Browser startOffset automatisch an, wenn sich das DOM ändert. Bei einem StaticRange passiert das nicht. Der Wert kann dann veraltet oder sogar größer als die Länge des Knotens sein.
  • Schreibgeschützt: Eine Zuweisung wird stillschweigend ignoriert, im Strict Mode löst sie einen TypeError aus. Verwende stattdessen Range.setStart().
  • Kompatibilität: startOffset gibt es bei Range in allen Browsern schon seit Langem. Die gemeinsame Basis AbstractRange und StaticRange stehen ungefähr seit Chrome 90, Firefox 69 und Safari 14.1 zur Verfügung.