Signatur
Beschreibung
Das mark-Ereignis gehört zur Web Speech API und wird an einer SpeechSynthesisUtterance ausgelöst, sobald die Sprachsynthese im gesprochenen Text ein SSML-Element <mark name="…"/> erreicht. Damit lässt sich die Sprachausgabe mit anderen Aktionen synchronisieren, etwa um Folien umzuschalten, Textabschnitte hervorzuheben oder Animationen passend zum Gesagten zu starten.
Du kannst das Ereignis mit addEventListener("mark", handler) abonnieren oder die Eigenschaft onmark setzen. Der Handler erhält ein SpeechSynthesisEvent. Dessen Eigenschaft name enthält den Namen des erreichten Markers, charIndex die Zeichenposition im Text und elapsedTime die seit Beginn der Ausgabe vergangene Zeit in Millisekunden.
Das Ereignis funktioniert nur, wenn die Sprach-Engine SSML tatsächlich auswertet. In der Praxis tun das die meisten Browser nicht: Sie lesen das SSML-Markup entweder wörtlich vor oder entfernen es stillschweigend, und mark wird nie ausgelöst. Für eine verlässliche Synchronisation eignet sich meist das boundary-Ereignis mit Wort- und Satzgrenzen besser.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier "mark". |
|
| $handler Pflicht | (event: SpeechSynthesisEvent) => void | Callback, der ein SpeechSynthesisEvent erhält. Wichtige Eigenschaften: name (Name des Markers), charIndex, charLength, elapsedTime und utterance. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once oder signal. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein SpeechSynthesisEvent.Beispiele
Marker per addEventListener auswerten
const ssml = `<?xml version="1.0"?>
<speak version="1.1" xmlns="http://www.w3.org/2001/10/synthesis">
Willkommen zur Präsentation. <mark name="folie2"/> Hier sehen Sie die Zahlen.
<mark name="folie3"/> Und hier das Fazit.
</speak>`;
const utterance = new SpeechSynthesisUtterance(ssml);
utterance.lang = 'de-DE';
utterance.addEventListener('mark', (event) => {
console.log(`Marker "${event.name}" nach ${Math.round(event.elapsedTime)} ms erreicht`);
});
speechSynthesis.speak(utterance);
Folien über die Eigenschaft onmark umschalten
const slides = {
intro: document.querySelector('#slide-intro'),
daten: document.querySelector('#slide-daten'),
fazit: document.querySelector('#slide-fazit')
};
const showSlide = (name) => {
Object.values(slides).forEach((el) => el?.classList.remove('active'));
slides[name]?.classList.add('active');
};
const utterance = new SpeechSynthesisUtterance(
'<speak><mark name="intro"/>Einleitung. <mark name="daten"/>Die Daten. <mark name="fazit"/>Fazit.</speak>'
);
utterance.onmark = (event) => showSlide(event.name);
utterance.onend = () => console.log('Vortrag beendet');
speechSynthesis.speak(utterance);
Listener entfernen und auf boundary ausweichen
const utterance = new SpeechSynthesisUtterance('<speak>Eins <mark name="m1"/> zwei</speak>');
let markSeen = false;
const onMark = (event) => {
markSeen = true;
console.log('mark:', event.name);
};
utterance.addEventListener('mark', onMark);
// Fallback: Wortgrenzen funktionieren in deutlich mehr Browsern
utterance.addEventListener('boundary', (event) => {
if (event.name === 'word') console.log('Wort bei Index', event.charIndex);
});
utterance.addEventListener('end', () => {
utterance.removeEventListener('mark', onMark);
if (!markSeen) console.warn('Keine mark-Ereignisse – Engine unterstützt vermutlich kein SSML');
});
speechSynthesis.speak(utterance);
// Wichtig · Fallstricke
- Kaum unterstützt: Chrome, Firefox und Safari verarbeiten SSML in
SpeechSynthesisUtterancein der Regel nicht. Das Markup wird dann vorgelesen oder entfernt, undmarkwird nicht ausgelöst. Verlass dich deshalb nicht allein auf dieses Ereignis. - Ob SSML ausgewertet wird, hängt auch von der Sprach-Engine des Betriebssystems ab (lokale Stimmen gegenüber Netzwerkstimmen). Teste das Verhalten auf jeder Zielplattform.
- Das SSML-Dokument muss wohlgeformt sein. Fehlerhaftes Markup kann dazu führen, dass die Engine es als reinen Text behandelt.
- Einen zuverlässigeren Ersatz bietet das
boundary-Ereignis, das bei Wort- und Satzgrenzen auslöst. Damit kannst du selbst Positionen im Text zuordnen. - In Chrome kann die Ausgabe nach etwa 15 Sekunden abbrechen; bei langen Texten sollten Utterances aufgeteilt werden.