Start · Sprachen · JavaScript · Referenz · CharacterBoundsUpdateEvent.rangeStart

CharacterBoundsUpdateEvent.rangeStart

Eigenschaft

Liefert den Offset des ersten Zeichens im bearbeitbaren Text, für das das Betriebssystem die Zeichenbegrenzungen (Bildschirmrechtecke) anfordert.

seit JavaScript Experimentell: Chrome/Edge 121+ (EditContext API) Kategorie: webapi

Signatur

CharacterBoundsUpdateEvent.rangeStart

Beschreibung

Die schreibgeschützte Eigenschaft rangeStart gehört zum CharacterBoundsUpdateEvent der EditContext API. Dieses Ereignis wird an einem EditContext ausgelöst, wenn das Betriebssystem bzw. der Eingabemethoden-Editor (IME) wissen muss, wo bestimmte Zeichen auf dem Bildschirm stehen. Das kommt zum Beispiel vor, wenn ein Kandidatenfenster für chinesische oder japanische Eingabe direkt unter dem gerade eingegebenen Text erscheinen soll.

rangeStart gibt den Index des ersten Zeichens (in UTF-16-Codeeinheiten, bezogen auf editContext.text) an, für das Begrenzungen benötigt werden. Zusammen mit rangeEnd ergibt sich der halboffene Bereich [rangeStart, rangeEnd). Die Anwendung berechnet für jedes Zeichen in diesem Bereich ein DOMRect und meldet es mit editContext.updateCharacterBounds(rangeStart, rects) zurück.

Gebraucht wird die Eigenschaft vor allem in eigenen Editoren, die ihren Text selbst zeichnen, etwa in einem <canvas> oder mit eigenem DOM-Aufbau. Dort weiß der Browser nicht von selbst, wo die Zeichen liegen. Deshalb muss die Anwendung genau den angefragten Bereich ab rangeStart ausmessen.

Rückgabewert

Typ
number
Beschreibung
Eine nicht-negative Ganzzahl: der Offset des ersten Zeichens im Text des EditContext, für das Begrenzungen angefordert werden. Gezählt wird in UTF-16-Codeeinheiten.

Beispiele

Angefragten Bereich protokollieren

const editor = document.querySelector('#editor');
const editContext = new EditContext();
editor.editContext = editContext;

editContext.addEventListener('characterboundsupdate', (event) => {
  console.log(`Begrenzungen benötigt für Zeichen ${event.rangeStart} bis ${event.rangeEnd - 1}`);
});
Begrenzungen benötigt für Zeichen 4 bis 6

Zeichenbegrenzungen in einem Canvas-Editor zurückmelden

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '20px monospace';
const editContext = new EditContext();
canvas.editContext = editContext;

const LINE_TOP = 10;
const LINE_HEIGHT = 24;

editContext.addEventListener('characterboundsupdate', (event) => {
  const { rangeStart, rangeEnd } = event;
  const text = editContext.text;
  const canvasRect = canvas.getBoundingClientRect();
  const rects = [];

  for (let i = rangeStart; i < rangeEnd; i++) {
    // x-Position = Breite des Textes vor dem Zeichen
    const x = ctx.measureText(text.slice(0, i)).width;
    const width = ctx.measureText(text[i] ?? '').width;
    rects.push(new DOMRect(canvasRect.left + x, canvasRect.top + LINE_TOP, width, LINE_HEIGHT));
  }

  // Erster Parameter MUSS rangeStart sein
  editContext.updateCharacterBounds(rangeStart, rects);
});

Begrenzungen aus DOM-Textknoten per Range ermitteln

const editor = document.querySelector('#editor');
const editContext = new EditContext();
editor.editContext = editContext;

editContext.addEventListener('characterboundsupdate', ({ rangeStart, rangeEnd }) => {
  const textNode = editor.firstChild; // der Editor rendert den Text als einzelnen Textknoten
  if (!textNode) return;

  const range = document.createRange();
  const rects = [];
  for (let i = rangeStart; i < rangeEnd; i++) {
    range.setStart(textNode, i);
    range.setEnd(textNode, i + 1);
    rects.push(range.getBoundingClientRect());
  }
  editContext.updateCharacterBounds(rangeStart, rects);
  console.log(`${rects.length} Rechtecke ab Offset ${rangeStart} gemeldet`);
});
3 Rechtecke ab Offset 4 gemeldet

// Wichtig · Fallstricke

Kompatibilität: Die EditContext API ist experimentell und bisher nur in Chromium-Browsern verfügbar (Chrome/Edge ab Version 121). Firefox und Safari unterstützen sie nicht. Vor der Nutzung sollte man die Unterstützung prüfen, etwa mit 'EditContext' in window.

  • Der Wert ist schreibgeschützt. Eine Zuweisung wird stillschweigend ignoriert und löst im Strict Mode einen Fehler aus.
  • Offsets zählen in UTF-16-Codeeinheiten, nicht in Graphemen. Emojis oder Zeichen außerhalb der BMP belegen zwei Positionen.
  • Der Bereich ist halboffen: rangeEnd ist exklusiv. Das Array für updateCharacterBounds() sollte daher genau rangeEnd - rangeStart Einträge enthalten.
  • Die Rechtecke müssen in Viewport-Koordinaten angegeben werden, also relativ zum sichtbaren Fensterbereich. Bei Canvas-Editoren muss man daher den Versatz aus getBoundingClientRect() addieren.
  • Das Ereignis kann während einer IME-Komposition oft ausgelöst werden. Die Berechnung sollte daher schnell sein, zum Beispiel über zwischengespeicherte Glyphenbreiten.