Start · Sprachen · JavaScript · Referenz · AbstractRange

AbstractRange

Schnittstelle

Abstrakte Basisschnittstelle für alle DOM-Bereichstypen wie <code>Range</code> und <code>StaticRange</code>; definiert Start, Ende und den Zustand „zusammengefallen“.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2020/202 Kategorie: webapi

Signatur

interface AbstractRange

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 aus InputEvent.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

Typ
AbstractRange
Beschreibung
Kein direkter Rückgabewert – die Schnittstelle ist abstrakt. Konkrete Instanzen sind stets 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());
TypeError true true Hallo

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));
{ start: '#text@3', end: '#text@3', collapsed: true }

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);
  }
});
z. B. beim Löschen eines Zeichens: deleteContentBackward 3 4 false

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()));
  }
}
z. B.: Ausgewählt: "Welt"

// Wichtig · Fallstricke

  • Nicht instanziierbar: new AbstractRange() wirft einen TypeError. Verwenden Sie document.createRange(), new Range() oder new StaticRange({...}).
  • Lebendig vs. statisch: Nur Range passt sich bei DOM-Änderungen an. Ein StaticRange kann nach Änderungen auf ungültige Positionen zeigen (z. B. einen Versatz größer als die Knotenlänge) – vor der Weiterverwendung prüfen oder in einen Range umwandeln.
  • 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 AbstractRange als globales Objekt existiert in Chrome/Edge ab 90, Firefox ab 69 und Safari ab 14.1. In älteren Browsern ist Range zwar vorhanden, eine Prüfung mit instanceof AbstractRange schlägt dort aber fehl – ggf. mit typeof AbstractRange !== 'undefined' absichern. In Node.js gibt es die Schnittstelle nur über DOM-Implementierungen wie jsdom.