Start · Sprachen · JavaScript · Referenz · HTMLMediaElement: progress

HTMLMediaElement: progress

Ereignis

Wird regelmäßig ausgelöst, während der Browser Mediendaten eines <code>&lt;audio&gt;</code>- oder <code>&lt;video&gt;</code>-Elements herunterlädt.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

element.addEventListener("progress", handler)

Beschreibung

Das progress-Ereignis eines HTMLMediaElement (also <audio> oder <video>) wird periodisch ausgelöst, solange der Browser Daten der Medienressource lädt. Laut Spezifikation geschieht das etwa alle 350 ms bzw. immer dann, wenn neue Daten eingetroffen sind. Das Ereignis ist nicht abbrechbar und bubbelt nicht.

Typischer Einsatz ist eine Pufferanzeige: Im Handler liest man media.buffered (ein TimeRanges-Objekt) aus und vergleicht das Ende des gepufferten Bereichs mit media.duration. So lässt sich z. B. ein grauer „Geladen“-Balken hinter der eigentlichen Fortschrittsleiste eines eigenen Players zeichnen.

Anders als das gleichnamige Ereignis von XMLHttpRequest ist das Media-progress-Ereignis ein einfaches Event – es besitzt keine Eigenschaften loaded, total oder lengthComputable. Den Ladestand ermittelt man ausschließlich über buffered.

Registrierung erfolgt entweder per addEventListener("progress", handler) oder über die Eigenschaft onprogress. Endet der Download, folgt meist suspend; bei Stillstand stalled.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "progress".
$handler Pflicht (event: Event) => void Callback, der bei jedem Ladefortschritt aufgerufen wird. Erhält ein einfaches Event; event.target ist das Medienelement.
$options boolean | AddEventListenerOptions false Optionen wie once, passive oder signal (zum Entfernen per AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein Event-Objekt.

Beispiele

Pufferstand in Prozent anzeigen

const video = document.querySelector('video');
const anzeige = document.querySelector('#puffer');

const aktualisierePuffer = () => {
  const { buffered, duration } = video;
  if (!buffered.length || !Number.isFinite(duration)) return;
  // Ende des letzten gepufferten Bereichs
  const ende = buffered.end(buffered.length - 1);
  const prozent = Math.round((ende / duration) * 100);
  anzeige.textContent = `Geladen: ${prozent} %`;
};

video.addEventListener('progress', aktualisierePuffer);
Geladen: 12 % Geladen: 27 % ...

Pufferbalken für eigenen Player (relativ zur Abspielposition)

const audio = document.querySelector('audio');
const balken = document.querySelector('.buffer-bar');

audio.addEventListener('progress', () => {
  const { buffered, currentTime, duration } = audio;
  // Den Bereich suchen, der die aktuelle Position enthält
  for (let i = 0; i < buffered.length; i++) {
    if (buffered.start(i) <= currentTime && currentTime <= buffered.end(i)) {
      balken.style.width = `${(buffered.end(i) / duration) * 100}%`;
      break;
    }
  }
});

onprogress-Eigenschaft und Entfernen des Listeners

const video = document.querySelector('video');

// Variante 1: on-Property (überschreibt vorherige Zuweisung)
video.onprogress = () => console.log('Daten werden geladen …');

// Variante 2: addEventListener mit späterem Entfernen
const logProgress = () => console.log('Gepufferte Bereiche:', video.buffered.length);
video.addEventListener('progress', logProgress);

// Sobald vollständig abspielbar, Listener entfernen
video.addEventListener('canplaythrough', () => {
  video.removeEventListener('progress', logProgress);
  video.onprogress = null;
  console.log('Listener entfernt');
}, { once: true });
Daten werden geladen … Gepufferte Bereiche: 1 ... Listener entfernt

// Wichtig · Fallstricke

  • Keine loaded/total-Werte: Anders als bei XMLHttpRequest oder FileReader ist das Ereignis ein einfaches Event. Fortschritt immer über media.buffered berechnen.
  • duration prüfen: Vor loadedmetadata ist duration NaN, bei Livestreams Infinity – Division vorher absichern.
  • Mehrere Bereiche: buffered kann nach Sprüngen (Seeking) mehrere, nicht zusammenhängende Bereiche enthalten. buffered.end(buffered.length - 1) liefert nur das Ende des letzten Bereichs.
  • Kein garantiertes Intervall: Bei preload="none" oder preload="metadata" wird eventuell kaum oder gar kein progress ausgelöst. Browser (v. a. mobile) drosseln zudem das Vorladen; mit Media Source Extensions hängt das Verhalten vom Anwendungscode ab.
  • Aus dem Cache: Bei bereits vollständig gecachten Medien kann das Ereignis nur einmal oder gar nicht erscheinen – den Pufferstand zusätzlich bei loadedmetadata/canplaythrough aktualisieren.
  • Das Ereignis bubbelt nicht; Delegation über einen Elternknoten funktioniert nur mit capture: true.
  • Browser-Unterstützung: in allen modernen Browsern seit Langem verfügbar.