Signatur
Beschreibung
Der Konstruktor StaticRange() legt einen statischen Bereich im DOM an. Wie ein Range wird er durch einen Startpunkt (startContainer/startOffset) und einen Endpunkt (endContainer/endOffset) festgelegt. Anders als ein Range wird ein StaticRange aber nicht automatisch angepasst, wenn sich das DOM ändert. Nach dem Erzeugen kann man ihn auch nicht mehr verändern.
Deshalb ist ein StaticRange deutlich leichtgewichtiger. Der Browser muss ihn bei DOM-Änderungen nicht mitverfolgen. Das lohnt sich, wenn man viele Bereiche braucht, etwa für die CSS Custom Highlight API (Suchtreffer, Rechtschreibmarkierungen, Syntaxhervorhebung). Auch bei InputEvent.getTargetRanges() kommen solche Bereiche vor. Dort gibt der Browser selbst StaticRange-Objekte zurück.
Der Konstruktor prüft die Offsets nicht gegen die tatsächliche Länge der Knoten. Ein Offset außerhalb des gültigen Bereichs oder ein Endpunkt vor dem Startpunkt führt also nicht zu einem Fehler. Braucht man die Inhalte des Bereichs (Text, Fragmente, Begrenzungsrechtecke), muss man ihn vorher in einen echten Range umwandeln.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $rangeSpec Pflicht | { startContainer: Node, startOffset: number, endContainer: Node, endOffset: number } | Objekt mit allen vier Pflicht-Eigenschaften. startContainer/endContainer sind die Knoten, in denen der Bereich beginnt bzw. endet. startOffset/endOffset geben die Position darin an: Bei Text-, Kommentar- und CDATA-Knoten ist das der Zeichenindex, bei allen anderen Knoten der Index des Kindknotens. |
Rückgabewert
StaticRange-Objekt mit den schreibgeschützten Eigenschaften startContainer, startOffset, endContainer, endOffset und collapsed.Beispiele
Bereich über einen Teil eines Textknotens anlegen
const p = document.createElement('p');
p.textContent = 'Hallo Welt, schöner Tag!';
const text = p.firstChild;
// Markiert das Wort „Welt“ (Zeichen 6 bis 10)
const bereich = new StaticRange({
startContainer: text,
startOffset: 6,
endContainer: text,
endOffset: 10
});
console.log(bereich.startOffset, bereich.endOffset, bereich.collapsed);
Suchtreffer mit der CSS Custom Highlight API hervorheben
// CSS: ::highlight(suche) { background: yellow; }
const markiereTreffer = (element, suchbegriff) => {
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT);
const bereiche = [];
let knoten;
while ((knoten = walker.nextNode())) {
const inhalt = knoten.textContent.toLowerCase();
let pos = inhalt.indexOf(suchbegriff.toLowerCase());
while (pos !== -1) {
bereiche.push(new StaticRange({
startContainer: knoten,
startOffset: pos,
endContainer: knoten,
endOffset: pos + suchbegriff.length
}));
pos = inhalt.indexOf(suchbegriff.toLowerCase(), pos + 1);
}
}
if ('highlights' in CSS) {
CSS.highlights.set('suche', new Highlight(...bereiche));
}
return bereiche.length;
};
console.log(markiereTreffer(document.body, 'javascript'));
StaticRange in einen Range umwandeln, um den Text auszulesen
const div = document.createElement('div');
div.innerHTML = '<b>Fett</b> und <i>kursiv</i>';
// Von Kind 0 bis Kind 3 des div (alle drei Kindknoten)
const statisch = new StaticRange({
startContainer: div,
startOffset: 0,
endContainer: div,
endOffset: 3
});
const zuRange = (sr) => {
const r = document.createRange();
r.setStart(sr.startContainer, sr.startOffset);
r.setEnd(sr.endContainer, sr.endOffset);
return r;
};
console.log(zuRange(statisch).toString());
Unterschied zu Range: keine Aktualisierung bei DOM-Änderungen
const p = document.createElement('p');
p.append('A', 'B', 'C');
const live = document.createRange();
live.setStart(p, 1);
live.setEnd(p, 2);
const fest = new StaticRange({ startContainer: p, startOffset: 1, endContainer: p, endOffset: 2 });
p.firstChild.remove(); // „A“ entfernen
console.log(live.startOffset, live.endOffset); // angepasst
console.log(fest.startOffset, fest.endOffset); // unverändert
// Wichtig · Fallstricke
- Keine Offset-Prüfung: Ungültige Offsets oder vertauschte Endpunkte werden stillschweigend übernommen. Fehler zeigen sich erst später, etwa beim Umwandeln in einen
Range(IndexSizeError). Vorher selbst prüfen oder den Bereich überRangeabsichern. - Ungültige Knotentypen: Ist
startContaineroderendContainereinDocumentType- oderAttr-Knoten, wirft der Konstruktor eineDOMExceptionvom TypInvalidNodeTypeError. - Veraltet nach DOM-Änderungen: Der Bereich passt sich nicht an. Nach Einfügen oder Entfernen von Knoten können die Offsets auf falsche Inhalte zeigen. In dynamischen Dokumenten die Bereiche nach Änderungen neu berechnen.
- Kaum Methoden:
StaticRangehat wedertoString()nochgetBoundingClientRect(),cloneContents()o. Ä. Für diese Funktionen braucht man einenRange. - Kompatibilität: Die Schnittstelle selbst gibt es schon länger (z. B. über
getTargetRanges()). Den öffentlichen Konstruktor unterstützen aber erst Chrome/Edge 90, Firefox 71 und Safari 13.1. Für ältere Browser ist eine Funktionsprüfung wietypeof StaticRange === 'function'ratsam.