Signatur
Beschreibung
Der Konstruktor ProgressEvent() erzeugt ein synthetisches Fortschritts-Event. Normalerweise feuert der Browser solche Events selbst, etwa bei XMLHttpRequest, XMLHttpRequestUpload oder FileReader (loadstart, progress, load, loadend, error, abort, timeout).
Selbst erzeugen lohnt sich vor allem, wenn eigene Komponenten Fortschritt nach dem gleichen Muster melden sollen, zum Beispiel ein Upload-Wrapper um fetch() mit Streams, ein eigener Worker-Job oder Unit-Tests, die Fortschrittsanzeigen ohne echte Netzwerkanfrage prüfen.
Über das options-Objekt legst du lengthComputable, loaded und total fest. Zusätzlich gelten die üblichen EventInit-Optionen bubbles, cancelable und composed. Die Werte sind danach nur lesbar und lassen sich nicht mehr ändern.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Events, zum Beispiel "progress", "load" oder "loadend". Groß- und Kleinschreibung zählen. |
|
| $options | ProgressEventInit | {} | Optionales Objekt mit folgenden Feldern:
|
Rückgabewert
ProgressEvent-Objekt mit den angegebenen Werten. Es kann mit dispatchEvent() auf einem beliebigen EventTarget ausgelöst werden.Beispiele
Einfaches ProgressEvent erzeugen und auslesen
const event = new ProgressEvent('progress', {
lengthComputable: true,
loaded: 256,
total: 1024
});
const prozent = Math.round((event.loaded / event.total) * 100);
console.log(event.type, event.lengthComputable, `${prozent} %`);
Eigener Uploader meldet Fortschritt per EventTarget
class Uploader extends EventTarget {
async upload(chunks) {
const total = chunks.reduce((sum, c) => sum + c.byteLength, 0);
let loaded = 0;
this.dispatchEvent(new ProgressEvent('loadstart', { lengthComputable: true, total }));
for (const chunk of chunks) {
await new Promise((r) => setTimeout(r, 50)); // simulierter Versand
loaded += chunk.byteLength;
this.dispatchEvent(new ProgressEvent('progress', { lengthComputable: true, loaded, total }));
}
this.dispatchEvent(new ProgressEvent('loadend', { lengthComputable: true, loaded, total }));
}
}
const uploader = new Uploader();
uploader.addEventListener('progress', (e) => {
console.log(`Fortschritt: ${Math.round((e.loaded / e.total) * 100)} %`);
});
uploader.addEventListener('loadend', () => console.log('Fertig'));
uploader.upload([new ArrayBuffer(500), new ArrayBuffer(500)]);
Fortschrittsbalken ohne Netzwerk testen
const bar = document.createElement('progress');
bar.max = 100;
const onProgress = (e) => {
bar.value = e.lengthComputable ? (e.loaded / e.total) * 100 : 0;
};
bar.addEventListener('progress', onProgress);
// XHR-Fortschritt simulieren
bar.dispatchEvent(new ProgressEvent('progress', { lengthComputable: true, loaded: 3, total: 4 }));
console.log(bar.value);
// Wichtig · Fallstricke
- Selbst erzeugte Events haben
isTrusted === false. Sicherheitsrelevanter Code sollte sich darauf nicht verlassen. - Ist
lengthComputablegleichfalse, isttotalmeist0. Prüfe das vor jeder Division, sonst kommtNaNoderInfinityheraus. loadedundtotalsind laut Spezifikationunsigned long long. Negative Werte werden umgerechnet, lass sie also weg.- Die Eigenschaften sind nur lesbar. Für einen neuen Stand erzeugst du ein neues Event.
- Ohne
newaufgerufen wirft der Konstruktor einenTypeError. Sehr alte Browser wie der Internet Explorer unterstützen ihn nicht, dort war nurdocument.createEvent('ProgressEvent')verfügbar. fetch()feuert keine ProgressEvents. Fortschritt musst du dort überReadableStreamselbst ermitteln, zum Beispiel mit dem Konstruktor wie in Beispiel 2.