Signatur
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
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);
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 });
// Wichtig · Fallstricke
- Keine
loaded/total-Werte: Anders als beiXMLHttpRequestoderFileReaderist das Ereignis ein einfachesEvent. Fortschritt immer übermedia.bufferedberechnen. durationprüfen: VorloadedmetadataistdurationNaN, bei LivestreamsInfinity– Division vorher absichern.- Mehrere Bereiche:
bufferedkann 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"oderpreload="metadata"wird eventuell kaum oder gar keinprogressausgelö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/canplaythroughaktualisieren. - Das Ereignis bubbelt nicht; Delegation über einen Elternknoten funktioniert nur mit
capture: true. - Browser-Unterstützung: in allen modernen Browsern seit Langem verfügbar.