Start · Sprachen · JavaScript · Referenz · new StaticRange()

new StaticRange()

Methode

Erstellt ein neues, unveränderliches <code>StaticRange</code>-Objekt, das einen festen Bereich im DOM anhand von Start- und Endknoten samt Offsets beschreibt.

seit JavaScript Baseline: Chrome 90+, Edge 90+, Firefox 71+, Safar Kategorie: webapi

Signatur

new StaticRange(rangeSpec)

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

Typ
StaticRange
Beschreibung
Ein neues 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);
6 10 false

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'));
z. B. 3 (Anzahl der Treffer)

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());
Fett und kursiv

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
0 1 1 2

// 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 über Range absichern.
  • Ungültige Knotentypen: Ist startContainer oder endContainer ein DocumentType- oder Attr-Knoten, wirft der Konstruktor eine DOMException vom Typ InvalidNodeTypeError.
  • 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: StaticRange hat weder toString() noch getBoundingClientRect(), cloneContents() o. Ä. Für diese Funktionen braucht man einen Range.
  • 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 wie typeof StaticRange === 'function' ratsam.