Signatur
Beschreibung
Das change-Ereignis gehört zur Schnittstelle TextTrackList, die man über HTMLMediaElement.textTracks eines <video>- oder <audio>-Elements erhält. Es wird ausgelöst, wenn eine Textspur der Liste aktiviert oder deaktiviert wird. Das passiert, wenn sich ihre Eigenschaft mode zwischen "disabled", "hidden" und "showing" ändert, sei es per Skript oder über das eingebaute Untertitel-Menü des Browsers.
Typische Einsätze sind eigene Mediaplayer-Oberflächen: Die Untertitel-Schaltflächen sollen zum tatsächlichen Zustand passen, die Sprachwahl des Nutzers soll z. B. in localStorage gespeichert werden, oder Kapitel- und Metadatenspuren sollen ausgewertet werden, sobald sie aktiv sind.
Das Ereignis ist ein einfaches Event ohne zusätzliche Daten. Es bubbelt nicht und kann nicht abgebrochen werden. Welche Spur sich geändert hat, verrät es nicht. Man muss daher im Handler über die Liste laufen und den mode jeder Spur prüfen. Den Handler kann man mit addEventListener("change", …) oder über die Eigenschaft onchange registrieren.
Werden Spuren hinzugefügt oder entfernt, lösen stattdessen die Ereignisse addtrack und removetrack derselben Liste aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "change". |
|
| $handler Pflicht | (event: Event) => void | Callback, das ein einfaches Event erhält. event.target ist die betroffene TextTrackList. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal (zum Entfernen per AbortController) oder capture. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein Event-Objekt.Beispiele
Aktive Untertitelspur per addEventListener erkennen
const video = document.querySelector('video');
video.textTracks.addEventListener('change', (event) => {
const tracks = [...event.target];
const active = tracks.find((t) => t.mode === 'showing');
console.log(active ? `Aktiv: ${active.label} (${active.language})` : 'Keine Untertitel aktiv');
});
// Deutsche Untertitel per Skript einschalten (löst change aus)
const de = [...video.textTracks].find((t) => t.language === 'de');
if (de) de.mode = 'showing';
Sprachwahl über die onchange-Eigenschaft speichern
const video = document.querySelector('video');
video.textTracks.onchange = () => {
const active = [...video.textTracks].find((t) => t.mode === 'showing');
localStorage.setItem('subtitleLang', active?.language ?? 'off');
};
// Beim nächsten Laden gespeicherte Auswahl wiederherstellen
const saved = localStorage.getItem('subtitleLang');
for (const track of video.textTracks) {
track.mode = track.language === saved ? 'showing' : 'disabled';
}
// Handler wieder entfernen
// video.textTracks.onchange = null;
Listener mit AbortController wieder entfernen
const video = document.querySelector('video');
const controller = new AbortController();
const button = document.querySelector('#cc-button');
const syncButton = () => {
const on = [...video.textTracks].some((t) => t.mode === 'showing');
button.setAttribute('aria-pressed', String(on));
};
video.textTracks.addEventListener('change', syncButton, { signal: controller.signal });
// Beim Zerstören der Player-Komponente:
const destroyPlayer = () => controller.abort();
// Alternativ: video.textTracks.removeEventListener('change', syncButton);
// Wichtig · Fallstricke
- Das Ereignis enthält keine Angabe zur geänderten Spur. Man muss immer die ganze Liste durchsuchen.
- Setzt der Handler selbst
mode-Werte, kann das weiterechange-Ereignisse auslösen. Nur schreiben, wenn sich der Wert wirklich ändert, sonst droht eine Endlosschleife. - Browser bündeln Änderungen: Werden mehrere
mode-Werte in einem Durchlauf geändert, kommt meist nur einchange-Ereignis an, und zwar asynchron als Aufgabe (Task). - Hinzufügen oder Entfernen von
<track>-Elementen löstaddtrack/removetrackaus, nichtchange. - Kompatibilität: Chrome, Edge, Firefox und Safari unterstützen das Ereignis. In Safari kann das native Untertitel-Menü (vor allem im Vollbild auf iOS) die Spuren anders umschalten, als man es von eigenen Bedienelementen erwartet. Das sollte man auf echten Geräten testen.
- Bei Spuren von anderen Domains (z. B. über ein CDN) braucht das Medienelement das Attribut
crossoriginund der Server passende CORS-Header, sonst lädt die Spur nicht.