Start · Sprachen · JavaScript · Referenz · HTMLMediaElement: ended

HTMLMediaElement: ended

Ereignis

Wird ausgelöst, wenn die Wiedergabe eines <code>&lt;audio&gt;</code>- oder <code>&lt;video&gt;</code>-Elements stoppt, weil das Ende des Mediums erreicht wurde oder keine Daten mehr verfügbar sind.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

element.addEventListener("ended", handler)

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);
});
Wiedergabe beendet: https://example.com/intro.mp4 ended: true paused: true

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));
Spiele Titel 1 von 3 Spiele Titel 2 von 3 Spiele Titel 3 von 3 Playlist zu Ende

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;
Video vollständig angesehen – Statistik gesendet

// Wichtig · Fallstricke

  • Kein ended bei loop: Ist loop aktiv, wird das Ereignis nie ausgelöst. Um Durchläufe zu zählen, beobachtest du stattdessen timeupdate oder seeked.
  • Rückwärts abspielen: Bei negativer playbackRate (sofern der Browser das unterstützt) wird ended nicht ausgelöst, wenn der Anfang erreicht ist.
  • Kein Bubbling: Das Ereignis steigt nicht auf. Wer auf document lauscht, braucht { capture: true }.
  • Autoplay-Richtlinien: Wird im ended-Handler der nächste Titel mit play() gestartet, kann der Browser das ohne vorherige Nutzerinteraktion ablehnen. Behandle deshalb die abgelehnte Promise von play().
  • Streams und MediaSource: Bei Live-Streams wird ended oft nicht ausgelöst. Bei MSE erst dann, wenn mediaSource.endOfStream() aufgerufen wurde.
  • Bei once: true wird 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).