Start · Sprachen · JavaScript · Referenz · HTMLMediaElement: loadeddata

HTMLMediaElement: loadeddata

Ereignis

Wird ausgelöst, sobald der Frame an der aktuellen Wiedergabeposition eines <code>&lt;audio&gt;</code>- oder <code>&lt;video&gt;</code>-Elements geladen ist, meist der erste Frame.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

element.addEventListener("loadeddata", handler)

Beschreibung

Das Ereignis loadeddata tritt auf, wenn das Medienelement die Daten für die aktuelle Wiedergabeposition geladen hat. Dabei wechselt readyState erstmals auf mindestens HAVE_CURRENT_DATA (Wert 2). Bei einem Video ist das in der Regel der erste Frame, der sich jetzt anzeigen oder auf ein <canvas> zeichnen lässt.

Innerhalb der Ladeereignisse steht loadeddata nach loadstart, durationchange und loadedmetadata, aber vor canplay und canplaythrough. Deshalb eignet es sich gut, um Vorschaubilder (Thumbnails) zu erzeugen, einen Ladeindikator auszublenden oder Bedienelemente freizuschalten, die ein sichtbares Bild brauchen.

Sie können einen Handler mit addEventListener("loadeddata", handler) registrieren oder über die Eigenschaft onloadeddata zuweisen. Das Ereignis steigt nicht im DOM auf (bubbles: false) und lässt sich nicht abbrechen. Ein Listener muss deshalb direkt am Medienelement hängen, oder Sie fangen das Ereignis in der Capture-Phase ab.

loadeddata bedeutet nicht, dass genug Daten für eine flüssige Wiedergabe vorhanden sind. Dafür sind canplay bzw. canplaythrough zuständig.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "loadeddata".
$handler Pflicht (event: Event) => void Callback, das ein normales Event-Objekt erhält. event.target ist das auslösende HTMLMediaElement.
$options boolean | AddEventListenerOptions false Optionen wie { once: true }, capture oder signal (zum Entfernen über einen AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein Event ohne zusätzliche Eigenschaften.

Beispiele

Ladeindikator ausblenden, sobald der erste Frame da ist

const video = document.querySelector('#player');
const spinner = document.querySelector('.spinner');

const onLoadedData = (event) => {
  const media = event.target;
  console.log('readyState:', media.readyState);
  spinner.hidden = true;
};

video.addEventListener('loadeddata', onLoadedData);

// Später, z. B. beim Abbauen der Komponente:
// video.removeEventListener('loadeddata', onLoadedData);
readyState: 2

Vorschaubild aus dem ersten Frame erzeugen

const createThumbnail = (src) => new Promise((resolve, reject) => {
  const video = document.createElement('video');
  video.muted = true;
  video.preload = 'auto';
  video.crossOrigin = 'anonymous'; // nötig für fremde Quellen mit CORS
  video.src = src;

  video.addEventListener('loadeddata', () => {
    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0);
    resolve(canvas.toDataURL('image/jpeg', 0.8));
  }, { once: true });

  video.addEventListener('error', () => reject(video.error), { once: true });
});

const dataUrl = await createThumbnail('/media/clip.mp4');
document.querySelector('#thumb').src = dataUrl;
console.log(dataUrl.slice(0, 23));
data:image/jpeg;base64,

Zuweisung über die Eigenschaft onloadeddata

const audio = new Audio('/media/podcast.mp3');

audio.onloadeddata = () => {
  console.log(`Dauer: ${audio.duration.toFixed(1)} s – bereit für Anzeige`);
};

// Handler wieder entfernen:
// audio.onloadeddata = null;
Dauer: 1834.2 s – bereit für Anzeige

Race-Condition vermeiden: prüfen, ob die Daten schon geladen sind

const whenDataLoaded = (media) => new Promise((resolve) => {
  if (media.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
    resolve(media); // Ereignis ist bereits vorbei
  } else {
    media.addEventListener('loadeddata', () => resolve(media), { once: true });
  }
});

const video = document.querySelector('video');
await whenDataLoaded(video);
console.log('Erster Frame verfügbar');
Erster Frame verfügbar

// Wichtig · Fallstricke

  • Späte Registrierung: Wenn der Listener erst nach dem Laden angehängt wird, verpasst er das Ereignis. Prüfen Sie deshalb vorher readyState >= 2 (siehe Beispiel 4).
  • Kein Bubbling: document.addEventListener('loadeddata', …) reagiert nur mit capture: true.
  • Mobile Browser und preload: Safari auf iOS und viele Android-Browser laden bei preload="none" oder preload="metadata" ohne Nutzerinteraktion keine Framedaten. Dann feuert loadeddata erst nach play() oder load().
  • Canvas und CORS: Wenn Sie Frames aus fremden Quellen ohne passenden CORS-Header (und ohne crossOrigin) zeichnen, wird das Canvas „tainted“. toDataURL() bzw. getImageData() werfen dann einen SecurityError.
  • Mehrfaches Auslösen: Bei einem Wechsel von src oder einem Aufruf von load() kann das Ereignis erneut feuern. Nutzen Sie { once: true }, wenn Sie nur einmal reagieren wollen.
  • Schwarzer Frame: Manche Browser liefern bei loadeddata einen noch nicht dekodierten oder schwarzen Frame. Als robustere Alternative für Thumbnails bietet sich currentTime = 0.1 mit dem Ereignis seeked oder requestVideoFrameCallback() an.
  • Das Ereignis wird von allen modernen Browsern unterstützt (Baseline).