Signatur
Beschreibung
StaticRange erweitert AbstractRange und beschreibt einen Inhaltsbereich im DOM über einen Start- und einen Endpunkt (startContainer/startOffset bzw. endContainer/endOffset). Im Unterschied zu Range ist ein StaticRange eine reine Momentaufnahme: Wird der DOM-Baum danach verändert, passt der Browser die Grenzpunkte nicht an.
Da der Browser einen statischen Bereich nicht bei jeder Mutation nachführen muss, ist er deutlich günstiger als ein lebendiger Range. Deshalb verwenden Browser StaticRange etwa in InputEvent.getTargetRanges() (bei beforeinput) und in der CSS Custom Highlight API (Highlight). Dort beschreiben sie, welcher Text von einer Eingabe betroffen wäre bzw. welcher Text markiert werden soll.
Ein StaticRange hat nur die schreibgeschützten Eigenschaften startContainer, startOffset, endContainer, endOffset und collapsed. Methoden wie cloneContents(), deleteContents() oder getBoundingClientRect() gibt es nicht. Brauchst du sie, erzeugst du aus den Grenzpunkten einen normalen Range (siehe Beispiel).
Beim Erstellen prüft der Konstruktor nur, dass kein DocumentType- oder Attr-Knoten als Container übergeben wird. Ob die Offsets gültig sind oder der Start vor dem Ende liegt, prüft er nicht. Ein StaticRange kann also ungültig sein oder durch spätere DOM-Änderungen ungültig werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $rangeSpec Pflicht | { startContainer: Node, startOffset: number, endContainer: Node, endOffset: number } | Objekt mit den Grenzpunkten, das an den Konstruktor new StaticRange(rangeSpec) übergeben wird. Alle vier Felder sind Pflicht. |
|
| $rangeSpec.startContainer Pflicht | Node | Knoten, in dem der Bereich beginnt. Darf kein DocumentType- oder Attr-Knoten sein, sonst wird ein InvalidNodeTypeError ausgelöst. |
|
| $rangeSpec.startOffset Pflicht | number | Position im Startknoten: bei Textknoten der Zeichenindex, bei Elementen der Index des Kindknotens. | |
| $rangeSpec.endContainer Pflicht | Node | Knoten, in dem der Bereich endet. Es gelten dieselben Einschränkungen wie bei startContainer. |
|
| $rangeSpec.endOffset Pflicht | number | Position im Endknoten, wird genauso ausgewertet wie startOffset. |
Rückgabewert
StaticRange-Objekt mit den angegebenen Grenzpunkten zurück.Beispiele
StaticRange erzeugen und auslesen
const p = document.createElement('p');
p.textContent = 'Hallo Welt';
const text = p.firstChild;
const range = new StaticRange({
startContainer: text,
startOffset: 6,
endContainer: text,
endOffset: 10
});
console.log(range.startOffset, range.endOffset); // 6 10
console.log(range.collapsed); // false
console.log(text.data.slice(range.startOffset, range.endOffset));
Statisch vs. lebendig: Verhalten bei DOM-Änderungen
const div = document.createElement('div');
div.innerHTML = '<b>A</b><i>B</i><u>C</u>';
const live = document.createRange();
live.setStart(div, 2);
live.setEnd(div, 3);
const fixed = new StaticRange({
startContainer: div, startOffset: 2,
endContainer: div, endOffset: 3
});
// Erstes Kind entfernen
div.firstChild.remove();
console.log('Range:', live.startOffset, live.endOffset);
console.log('StaticRange:', fixed.startOffset, fixed.endOffset);
Betroffenen Text bei beforeinput ermitteln
const editor = document.querySelector('[contenteditable]');
editor.addEventListener('beforeinput', (event) => {
const [target] = event.getTargetRanges(); // Array<StaticRange>
if (!target) return;
// In einen lebendigen Range umwandeln, um den Inhalt zu lesen
const range = document.createRange();
range.setStart(target.startContainer, target.startOffset);
range.setEnd(target.endContainer, target.endOffset);
console.log(`${event.inputType}: "${range.toString()}"`);
});
Text mit der CSS Custom Highlight API markieren
// CSS: ::highlight(treffer) { background: yellow; }
const textNode = document.querySelector('p').firstChild;
const index = textNode.data.indexOf('JavaScript');
if (index !== -1 && 'highlights' in CSS) {
const range = new StaticRange({
startContainer: textNode, startOffset: index,
endContainer: textNode, endOffset: index + 'JavaScript'.length
});
CSS.highlights.set('treffer', new Highlight(range));
}
// Wichtig · Fallstricke
- Keine Prüfung der Offsets: Der Konstruktor akzeptiert auch Offsets, die über die Länge des Knotens hinausgehen, oder einen Start, der hinter dem Ende liegt. Liest du damit später Text oder Kindknoten aus, kann das fehlschlagen. Beim Umwandeln in einen
RangelöstsetStart()/setEnd()dann einenIndexSizeErroraus. - Veraltete Grenzpunkte: Da sich ein
StaticRangenicht anpasst, kann er nach DOM-Änderungen auf falsche Stellen oder auf entfernte Knoten zeigen. Werte ihn daher möglichst direkt aus, z. B. noch im selbenbeforeinput-Handler. - Ungültige Knotentypen: Übergibst du einen
DocumentType- oderAttr-Knoten als Container, löst der Konstruktor einenInvalidNodeTypeErroraus (eineDOMException). - Nur wenige Funktionen: Methoden wie
toString(),getBoundingClientRect()oderextractContents()gibt es nur beiRange. - Leistung: Für viele Markierungen, etwa bei Suchtreffern mit der Highlight API, ist
StaticRangegünstiger alsRange, weil der Browser ihn nicht bei jeder DOM-Änderung nachführen muss. - Kompatibilität: Die Schnittstelle selbst gibt es schon länger. Den öffentlichen Konstruktor gibt es erst seit Chrome/Edge 90, Firefox 71 und Safari 13.1. In Node.js steht die Schnittstelle nur über DOM-Implementierungen wie jsdom zur Verfügung.