Signatur
Beschreibung
Das Ereignis seeked wird an einem HTMLMediaElement ausgelöst, wenn ein Suchvorgang (Spulen) abgeschlossen ist. Zu diesem Zeitpunkt hat sich currentTime auf die neue Position geändert und die Eigenschaft seeking ist wieder false. Ein Suchvorgang beginnt, wenn currentTime per Skript gesetzt, fastSeek() aufgerufen oder der Schieberegler der nativen Steuerelemente bewegt wird.
Das Gegenstück ist das Ereignis seeking, das zu Beginn eines Suchvorgangs feuert. Meist kombiniert man beide: Bei seeking blendet man z. B. einen Ladeindikator ein, bei seeked wieder aus. Außerdem eignet sich seeked gut, um nach dem Spulen Untertitel, Kapitelmarken oder Analyse-Daten zu aktualisieren oder einen Frame an einer bestimmten Position auf ein <canvas> zu zeichnen (z. B. für Vorschaubilder).
Registrieren kann man den Handler entweder mit addEventListener("seeked", handler) oder über die Eigenschaft onseeked. Das Ereignis ist ein einfaches Event, es ist nicht abbrechbar und steigt nicht im DOM auf (kein Bubbling).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "seeked". |
|
| $handler Pflicht | (event: Event) => void | Callback, der nach Abschluss des Suchvorgangs aufgerufen wird. event.target ist das Medienelement. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal oder capture. Da seeked nicht aufsteigt, braucht man capture: true, um das Ereignis an einem Vorfahren abzufangen. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein Event-Objekt ohne zusätzliche Eigenschaften.Beispiele
Ladeindikator beim Spulen ein- und ausblenden
const video = document.querySelector('video');
const spinner = document.querySelector('.spinner');
video.addEventListener('seeking', () => {
spinner.hidden = false;
});
video.addEventListener('seeked', () => {
spinner.hidden = true;
console.log(`Neue Position: ${video.currentTime.toFixed(2)} s, seeking = ${video.seeking}`);
});
Vorschaubild an einer bestimmten Stelle erzeugen (einmaliger Listener)
const captureFrame = (video, time) => new Promise((resolve) => {
video.addEventListener('seeked', () => {
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.currentTime = time;
});
const video = document.querySelector('video');
video.addEventListener('loadedmetadata', async () => {
const dataUrl = await captureFrame(video, 10);
document.querySelector('img.thumb').src = dataUrl;
console.log('Vorschaubild erstellt');
});
Handler über onseeked setzen und wieder entfernen
const audio = document.querySelector('audio');
audio.onseeked = (event) => {
console.log('Gespult zu', Math.round(event.target.currentTime), 's');
};
audio.currentTime = 30;
// Später: Handler wieder entfernen
setTimeout(() => {
audio.onseeked = null;
}, 5000);
Spul-Statistik mit AbortController aufräumen
const video = document.querySelector('video');
const controller = new AbortController();
let seekCount = 0;
video.addEventListener('seeked', () => {
seekCount += 1;
console.log(`Suchvorgänge bisher: ${seekCount}`);
}, { signal: controller.signal });
// Beim Verlassen der Ansicht alle Listener entfernen
window.addEventListener('pagehide', () => controller.abort());
// Wichtig · Fallstricke
- Kein Bubbling:
seekedsteigt nicht auf. Ereignisdelegation an einem Container klappt nur mitcapture: true. - Mehrfaches Spulen: Beginnt ein neuer Suchvorgang, bevor der vorherige fertig ist, wird der alte abgebrochen.
seekedfeuert dann meist nur einmal, für die letzte Position. Wer auf eine bestimmte Zielzeit wartet, sollte im HandlercurrentTimeprüfen. - Listener vor dem Spulen registrieren: Wenn der Listener erst nach dem Setzen von
currentTimeangemeldet wird, kann das Ereignis bei gepufferten Daten schon ausgelöst worden sein. - Genauigkeit:
fastSeek()springt zum nächstgelegenen Keyframe. NachseekedkanncurrentTimedeshalb vom gewünschten Wert abweichen. - Canvas und CORS: Stammt das Video von einer fremden Herkunft und fehlen
crossoriginbzw. passende CORS-Header, wird das Canvas „verunreinigt“ (tainted).toDataURL()wirft dann einenSecurityError. - Kompatibilität: Wird von allen modernen Browsern unterstützt, auch mobil.
seekedsagt nicht, ob danach schon abgespielt wird. Dafür gibt esplayingbzw.canplay.