Start · Sprachen · JavaScript · Referenz · SpeechSynthesisEvent.charIndex

SpeechSynthesisEvent.charIndex

Eigenschaft

Schreibgeschützte Zahl: Position des Zeichens in <code>SpeechSynthesisUtterance.text</code>, das gerade gesprochen wurde, als das Ereignis ausgelöst wurde.

seit JavaScript Baseline: alle modernen Browser (Web Speech API) Kategorie: webapi

Signatur

SpeechSynthesisEvent.charIndex

Beschreibung

Die schreibgeschützte Eigenschaft charIndex des SpeechSynthesisEvent-Interfaces liefert den nullbasierten Index des Zeichens in SpeechSynthesisUtterance.text, an dem die Sprachausgabe stand, als das Ereignis ausgelöst wurde. Beim boundary-Ereignis zeigt der Wert auf den Anfang des Wortes oder Satzes, der gleich gesprochen wird.

Am meisten bringt die Eigenschaft beim Ereignis boundary, zusammen mit charLength und name ("word" oder "sentence"). So lässt sich während des Vorlesens das aktuelle Wort hervorheben, etwa für Karaoke-artige Lesehilfen, Sprachlern-Apps oder Barrierefreiheit. Auch in pause, resume, end und error steht der Wert zur Verfügung. Damit kann man festhalten, wie weit ein Text schon vorgelesen wurde, und ihn später ab dieser Stelle fortsetzen.

Der Index zählt UTF-16-Codeeinheiten, genau wie String.prototype.slice() und String.prototype.length. Kann die Sprach-Engine keine Position ermitteln, ist der Wert 0.

Rückgabewert

Typ
number
Beschreibung
Nicht-negative Ganzzahl: nullbasierter Zeichenindex (in UTF-16-Codeeinheiten) in utterance.text.

Beispiele

Aktuelles Wort beim Vorlesen protokollieren

const text = 'Hallo Welt, wie geht es dir?';
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'de-DE';

utterance.addEventListener('boundary', (event) => {
  if (event.name !== 'word') return;
  const start = event.charIndex;
  // charLength fehlt in manchen Browsern – Wortende selbst suchen
  const end = event.charLength
    ? start + event.charLength
    : (text.slice(start).search(/[\s,.!?]/) + 1 || text.length - start + 1) + start - 1;
  console.log(start, text.slice(start, end));
});

speechSynthesis.speak(utterance);
0 Hallo 6 Welt 12 wie 16 geht 21 es 24 dir

Wort im DOM hervorheben (Lesehilfe)

const output = document.querySelector('#lesetext');
const text = output.textContent;
const utterance = new SpeechSynthesisUtterance(text);

const highlight = (start, length) => {
  output.replaceChildren(
    text.slice(0, start),
    Object.assign(document.createElement('mark'), {
      textContent: text.slice(start, start + length)
    }),
    text.slice(start + length)
  );
};

utterance.onboundary = (event) => {
  if (event.name === 'word') {
    const length = event.charLength || (text.slice(event.charIndex).match(/^\S+/)?.[0].length ?? 0);
    highlight(event.charIndex, length);
  }
};

utterance.onend = () => { output.textContent = text; };

speechSynthesis.speak(utterance);

Fortschritt merken und später an der Stelle weiterlesen

const text = 'Kapitel eins. Es war einmal ein kleiner Browser, der sprechen lernte.';
let lastIndex = 0;

const speakFrom = (index) => {
  const utterance = new SpeechSynthesisUtterance(text.slice(index));
  utterance.onboundary = (event) => {
    // charIndex bezieht sich auf den Teiltext, daher Offset addieren
    lastIndex = index + event.charIndex;
  };
  speechSynthesis.speak(utterance);
};

speakFrom(0);

// Nach 2 Sekunden abbrechen und später fortsetzen
setTimeout(() => {
  speechSynthesis.cancel();
  console.log('Abgebrochen bei Index', lastIndex);
  setTimeout(() => speakFrom(lastIndex), 1000);
}, 2000);
Abgebrochen bei Index 22

// Wichtig · Fallstricke

  • Abhängig von der Stimme: Ob und wie oft boundary-Ereignisse mit sinnvollem charIndex kommen, legt die Sprach-Engine fest. Manche Online- oder Fremdstimmen, etwa bestimmte Google-Stimmen in Chrome, lösen gar keine boundary-Ereignisse aus. Chrome unter Android liefert teils nur Satzgrenzen.
  • charLength ist nicht überall verfügbar: Ältere Safari- und Firefox-Versionen liefern kein charLength. Das Wortende muss man dann selbst aus charIndex und dem Text ermitteln.
  • Bezugspunkt: Der Index bezieht sich immer auf den Text der jeweiligen SpeechSynthesisUtterance. Teilt man einen langen Text auf mehrere Äußerungen auf, muss man den Versatz selbst dazurechnen.
  • Kodierung: Der Index zählt UTF-16-Codeeinheiten. Emojis und andere Zeichen außerhalb der BMP belegen zwei Einheiten. Bei SSML-Eingaben, soweit die Engine sie unterstützt, kann der Index vom sichtbaren Text abweichen.
  • Die Eigenschaft ist schreibgeschützt. Wer ihr etwas zuweist, bewirkt nichts (im Strict Mode kann das einen TypeError auslösen).