Signatur
Beschreibung
AbstractRange ist die gemeinsame, abstrakte Basisschnittstelle für Objekte, die einen Bereich im DOM-Baum beschreiben. Ein solcher Bereich wird durch zwei Randpunkte festgelegt, die jeweils aus einem Knoten (startContainer/endContainer) und einem Versatz (startOffset/endOffset) bestehen. Bei Textknoten zählt der Versatz Zeichen (genauer: UTF-16-Codeeinheiten), bei allen anderen Knoten die Kindknoten.
Die Schnittstelle kann nicht direkt instanziiert werden – new AbstractRange() wirft einen TypeError. In der Praxis arbeitet man mit einer der beiden konkreten Unterklassen:
Range– ein lebendiger Bereich, der sich bei DOM-Änderungen automatisch anpasst und viele Methoden zum Bearbeiten mitbringt (setStart(),deleteContents(),surroundContents()usw.).StaticRange– ein unveränderlicher, leichtgewichtiger Bereich, der bei DOM-Änderungen nicht aktualisiert wird, etwa ausInputEvent.getTargetRanges().
AbstractRange stellt ausschließlich schreibgeschützte Eigenschaften bereit: startContainer, startOffset, endContainer, endOffset und collapsed (true, wenn Start und Ende identisch sind, z. B. bei einer bloßen Cursorposition). Nützlich ist die Schnittstelle vor allem, wenn man Code schreiben will, der mit beiden Bereichstypen umgehen kann, oder um per instanceof AbstractRange zu prüfen, ob ein Objekt überhaupt ein Bereich ist.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $startContainer | Node | Schreibgeschützte Eigenschaft: der Knoten, in dem der Bereich beginnt. | |
| $startOffset | number | Schreibgeschützt: Position des Bereichsanfangs innerhalb von startContainer (Zeichen bei Textknoten, sonst Kindindex). |
|
| $endContainer | Node | Schreibgeschützt: der Knoten, in dem der Bereich endet. | |
| $endOffset | number | Schreibgeschützt: Position des Bereichsendes innerhalb von endContainer. |
|
| $collapsed | boolean | Schreibgeschützt: true, wenn Anfang und Ende auf dieselbe Position zeigen (leerer Bereich). |
Rückgabewert
Range oder StaticRange.Beispiele
Konkrete Unterklassen erzeugen und prüfen
// AbstractRange selbst ist nicht instanziierbar
try {
new AbstractRange();
} catch (err) {
console.log(err.constructor.name);
}
const p = document.createElement('p');
p.textContent = 'Hallo Welt';
document.body.append(p);
const live = document.createRange();
live.setStart(p.firstChild, 0);
live.setEnd(p.firstChild, 5);
const fixed = new StaticRange({
startContainer: p.firstChild,
startOffset: 6,
endContainer: p.firstChild,
endOffset: 10
});
console.log(live instanceof AbstractRange, fixed instanceof AbstractRange);
console.log(live.toString());
Generische Hilfsfunktion für Range und StaticRange
// Funktioniert mit jedem AbstractRange, da nur Basis-Eigenschaften genutzt werden
const describeRange = (range) => {
if (!(range instanceof AbstractRange)) {
throw new TypeError('Kein DOM-Bereich übergeben');
}
const { startContainer, startOffset, endContainer, endOffset, collapsed } = range;
return {
start: `${startContainer.nodeName}@${startOffset}`,
end: `${endContainer.nodeName}@${endOffset}`,
collapsed
};
};
const text = document.createTextNode('Beispieltext');
document.body.append(text);
const r = document.createRange();
r.setStart(text, 3);
r.collapse(true);
console.log(describeRange(r));
Zielbereiche einer Eingabe per beforeinput auslesen
// <div id="editor" contenteditable>Text hier bearbeiten</div>
const editor = document.querySelector('#editor');
editor.addEventListener('beforeinput', (event) => {
// getTargetRanges() liefert StaticRange-Objekte (Unterklasse von AbstractRange)
for (const range of event.getTargetRanges()) {
console.log(event.inputType, range.startOffset, range.endOffset, range.collapsed);
}
});
Aktuelle Auswahl des Nutzers analysieren
const selection = document.getSelection();
if (selection && selection.rangeCount > 0) {
const range = selection.getRangeAt(0); // Range extends AbstractRange
if (range.collapsed) {
console.log('Nur Cursor an Position', range.startOffset);
} else {
console.log('Ausgewählt:', JSON.stringify(range.toString()));
}
}
// Wichtig · Fallstricke
- Nicht instanziierbar:
new AbstractRange()wirft einenTypeError. Verwenden Siedocument.createRange(),new Range()odernew StaticRange({...}). - Lebendig vs. statisch: Nur
Rangepasst sich bei DOM-Änderungen an. EinStaticRangekann nach Änderungen auf ungültige Positionen zeigen (z. B. einen Versatz größer als die Knotenlänge) – vor der Weiterverwendung prüfen oder in einenRangeumwandeln. - Versätze bei Text: Offsets zählen UTF-16-Codeeinheiten, nicht sichtbare Zeichen. Emojis oder kombinierte Zeichen können daher zwei oder mehr Einheiten belegen.
- Nur Lesezugriff: Alle Eigenschaften sind schreibgeschützt; Änderungen erfolgen über Methoden von
Range(setStart(),setEnd(),collapse()). - Kompatibilität: Die Schnittstelle
AbstractRangeals globales Objekt existiert in Chrome/Edge ab 90, Firefox ab 69 und Safari ab 14.1. In älteren Browsern istRangezwar vorhanden, eine Prüfung mitinstanceof AbstractRangeschlägt dort aber fehl – ggf. mittypeof AbstractRange !== 'undefined'absichern. In Node.js gibt es die Schnittstelle nur über DOM-Implementierungen wie jsdom.