Signatur
Beschreibung
charLength ist eine schreibgeschützte Eigenschaft von SpeechSynthesisEvent. Zusammen mit charIndex gibt sie an, welcher Abschnitt des Texts in SpeechSynthesisUtterance.text gerade vorgelesen wird. charIndex ist die Startposition, charLength die Anzahl der Zeichen ab dieser Position.
Laut Spezifikation ist das die Länge des Worts oder Satzes, zu dem das Ereignis gehört. Die MDN-Formulierung „noch zu sprechende Zeichen“ ist in der Praxis ungenau. Bei boundary-Ereignissen mit name === "word" steht in charLength meist die Länge des aktuellen Worts. Mit text.substr(charIndex, charLength) bzw. text.slice(charIndex, charIndex + charLength) bekommen Sie also genau das Wort, das gerade gesprochen wird.
Typischer Einsatz ist das Hervorheben im Karaoke-Stil: Während der Text vorgelesen wird, wird das aktuelle Wort markiert, etwa in Vorlese-Funktionen, Lern-Apps oder Hilfen für Barrierefreiheit. Unterstützt die Sprach-Engine die Angabe nicht, ist der Wert 0. Bei Ereignissen wie start oder end ist er ebenfalls meist 0.
Rückgabewert
charIndex beginnt. 0, wenn die Engine keine Angabe macht.Beispiele
Aktuell gesprochenes Wort ausgeben
const text = 'Hallo Welt, heute ist ein schöner Tag.';
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'de-DE';
utterance.addEventListener('boundary', (event) => {
if (event.name !== 'word') return;
const { charIndex, charLength } = event;
const wort = text.slice(charIndex, charIndex + charLength);
console.log(`Index ${charIndex}, Länge ${charLength}: "${wort}"`);
});
speechSynthesis.speak(utterance);
Wort beim Vorlesen hervorheben (mit Ersatzlösung bei charLength = 0)
// HTML: <p id="ausgabe"></p>
const ausgabe = document.querySelector('#ausgabe');
const text = 'Die Web Speech API kann Texte vorlesen.';
// Ersatzlösung: Wortlänge selbst bestimmen, falls die Engine 0 liefert
const wortLaenge = (str, start) => {
const treffer = /^\S+/.exec(str.slice(start));
return treffer ? treffer[0].length : 0;
};
const escapeHtml = (s) => s.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'de-DE';
utterance.onboundary = (event) => {
if (event.name !== 'word') return;
const start = event.charIndex;
const laenge = event.charLength || wortLaenge(text, start);
ausgabe.innerHTML =
escapeHtml(text.slice(0, start)) +
'<mark>' + escapeHtml(text.slice(start, start + laenge)) + '</mark>' +
escapeHtml(text.slice(start + laenge));
};
utterance.onend = () => { ausgabe.textContent = text; };
speechSynthesis.speak(utterance);
Prüfen, ob die aktuelle Stimme charLength liefert
const utterance = new SpeechSynthesisUtterance('Test eins zwei');
let unterstuetzt = false;
utterance.addEventListener('boundary', (e) => {
if (typeof e.charLength === 'number' && e.charLength > 0) {
unterstuetzt = true;
}
});
utterance.addEventListener('end', () => {
console.log('charLength unterstützt:', unterstuetzt);
});
speechSynthesis.speak(utterance);
// Wichtig · Fallstricke
- Engine-abhängig: Ob
charLengtheinen sinnvollen Wert hat, hängt von Browser, Betriebssystem und Stimme ab. Manche Stimmen, z. B. Online-Stimmen in Chrome, lösen gar keineboundary-Ereignisse aus. Andere liefern nurcharIndexund setzencharLengthauf0. Ältere Browser kennen die Eigenschaft gar nicht, dann ist sieundefined. Planen Sie deshalb immer eine Ersatzlösung ein, etwa die Wortlänge per regulärem Ausdruck bestimmen. - Satzgrenzen: Bei
name === "sentence"kanncharLengtheinen ganzen Satz umfassen. Werten Sie deshalbevent.nameaus. - UTF-16: Gezählt werden Codeeinheiten, keine sichtbaren Zeichen. Emojis oder Zeichen außerhalb der BMP zählen doppelt. Verwenden Sie deshalb
slice()auf dem Originaltext, nichtArray.from(). - SSML/geänderter Text: Die Positionen beziehen sich auf
utterance.text. Wird der angezeigte Text anders formatiert, müssen Sie die Positionen selbst umrechnen. - Sicherheit: Wenn Sie zum Hervorheben mit
innerHTMLarbeiten, maskieren Sie den Text vorher, sonst drohen XSS-Lücken.