Signatur
Beschreibung
Das ended-Ereignis gehört zu HTMLMediaElement, also zu <audio> und <video>. Es wird ausgelöst, sobald die Wiedergabe das Ende erreicht hat. In diesem Moment ist media.ended gleich true und media.paused ebenfalls true.
Typische Einsätze sind Playlists (nächsten Titel automatisch starten), Hinweise nach dem Video wie „Nochmal ansehen“ oder weiterführende Inhalte, Statistiken zum vollständigen Ansehen und das Zurücksetzen der Oberfläche, etwa der Play-Schaltfläche.
Du registrierst den Handler mit addEventListener("ended", handler) oder über die Eigenschaft onended. Das Ereignis ist nicht abbrechbar (cancelable: false) und steigt nicht im DOM auf (bubbles: false). Delegation über ein übergeordnetes Element klappt deshalb nur in der Capture-Phase.
Wichtig: Ist das Attribut loop gesetzt (media.loop === true), wird ended nicht ausgelöst. Die Wiedergabe springt dann einfach wieder an den Anfang.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, hier "ended". |
|
| $handler Pflicht | (event: Event) => void | Funktion, die beim Ereignis aufgerufen wird. Sie erhält ein einfaches Event-Objekt; event.target ist das Medienelement. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie { once: true }, capture oder signal (zum Entfernen mit einem AbortController). |
Beispiele
Einfache Reaktion auf das Ende eines Videos
const video = document.querySelector("video");
video.addEventListener("ended", (event) => {
console.log("Wiedergabe beendet:", event.target.currentSrc);
console.log("ended:", video.ended, "paused:", video.paused);
});
Playlist: nächsten Titel automatisch abspielen
const audio = document.querySelector("#player");
const playlist = ["titel-1.mp3", "titel-2.mp3", "titel-3.mp3"];
let index = 0;
const playTrack = async (i) => {
audio.src = playlist[i];
try {
await audio.play();
console.log(`Spiele Titel ${i + 1} von ${playlist.length}`);
} catch (err) {
console.warn("Autoplay blockiert:", err.name);
}
};
audio.addEventListener("ended", () => {
index += 1;
if (index < playlist.length) {
playTrack(index);
} else {
console.log("Playlist zu Ende");
}
});
document.querySelector("#start").addEventListener("click", () => playTrack(0));
onended-Eigenschaft und Entfernen des Handlers
const video = document.querySelector("video");
const replayButton = document.querySelector("#replay");
// Variante 1: on-Eigenschaft (es gibt nur einen Handler)
video.onended = () => {
replayButton.hidden = false;
};
replayButton.addEventListener("click", () => {
replayButton.hidden = true;
video.currentTime = 0;
video.play();
});
// Variante 2: benannter Handler, der wieder entfernt wird
const trackCompletion = () => {
console.log("Video vollständig angesehen – Statistik gesendet");
navigator.sendBeacon("/api/stats", JSON.stringify({ event: "video_complete" }));
video.removeEventListener("ended", trackCompletion);
};
video.addEventListener("ended", trackCompletion);
// Handler der on-Eigenschaft entfernen
// video.onended = null;
// Wichtig · Fallstricke
- Kein
endedbeiloop: Istloopaktiv, wird das Ereignis nie ausgelöst. Um Durchläufe zu zählen, beobachtest du stattdessentimeupdateoderseeked. - Rückwärts abspielen: Bei negativer
playbackRate(sofern der Browser das unterstützt) wirdendednicht ausgelöst, wenn der Anfang erreicht ist. - Kein Bubbling: Das Ereignis steigt nicht auf. Wer auf
documentlauscht, braucht{ capture: true }. - Autoplay-Richtlinien: Wird im
ended-Handler der nächste Titel mitplay()gestartet, kann der Browser das ohne vorherige Nutzerinteraktion ablehnen. Behandle deshalb die abgelehnte Promise vonplay(). - Streams und MediaSource: Bei Live-Streams wird
endedoft nicht ausgelöst. Bei MSE erst dann, wennmediaSource.endOfStream()aufgerufen wurde. - Bei
once: truewird der Handler nach dem ersten Aufruf automatisch entfernt. Das passt für Einmal-Aktionen wie Statistiken. - Kompatibilität: wird seit Jahren von allen gängigen Browsern unterstützt (Baseline).