Signatur
Beschreibung
Das Ereignis enter gehört zur Schnittstelle DocumentPictureInPicture, die über window.documentPictureInPicture erreichbar ist. Es wird ausgelöst, nachdem documentPictureInPicture.requestWindow() ein neues, immer im Vordergrund schwebendes Fenster geöffnet hat. Das Ereignisobjekt ist ein DocumentPictureInPictureEvent. Seine Eigenschaft window verweist auf das Window-Objekt des neuen Bild-in-Bild-Fensters.
Den Handler registrierst du entweder mit documentPictureInPicture.addEventListener("enter", handler) oder über die Eigenschaft documentPictureInPicture.onenter. Das Ereignis lässt sich nicht abbrechen und steigt nicht im DOM auf (kein Bubbling).
Nützlich ist enter vor allem, wenn der Code, der das Fenster öffnet, und der Code, der darauf reagieren soll, getrennt sind. Beispiele: ein Analyse-Modul, eine Komponente, die ihre Oberfläche umschaltet (etwa einen Platzhalter „Wird im Bild-in-Bild-Fenster angezeigt“ einblendet), oder eine Logik, die Stylesheets ins neue Fenster kopiert. Für das Schließen gibt es kein eigenes Gegenstück-Ereignis. Stattdessen hörst du im Bild-in-Bild-Fenster selbst auf pagehide.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, hier immer "enter". |
|
| $handler Pflicht | (event: DocumentPictureInPictureEvent) => void | Callback-Funktion. Sie bekommt ein DocumentPictureInPictureEvent, dessen Eigenschaft event.window auf das geöffnete Bild-in-Bild-Fenster verweist. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once, signal oder capture. |
Rückgabewert
addEventListener gibt nichts zurück. Die Eigenschaft onenter enthält den aktuell zugewiesenen Handler oder null.Beispiele
Auf das Öffnen reagieren und Stile übernehmen
const kopiereStile = (zielFenster) => {
// Alle Stylesheets des Hauptdokuments ins Bild-in-Bild-Fenster übernehmen
for (const sheet of document.styleSheets) {
try {
const css = [...sheet.cssRules].map((r) => r.cssText).join('');
const style = zielFenster.document.createElement('style');
style.textContent = css;
zielFenster.document.head.append(style);
} catch {
// Fremde Stylesheets (CORS) per <link> einbinden
const link = zielFenster.document.createElement('link');
link.rel = 'stylesheet';
link.href = sheet.href;
zielFenster.document.head.append(link);
}
}
};
if ('documentPictureInPicture' in window) {
documentPictureInPicture.addEventListener('enter', (event) => {
const pipWindow = event.window;
console.log('Bild-in-Bild geöffnet:', pipWindow.innerWidth, 'x', pipWindow.innerHeight);
kopiereStile(pipWindow);
});
}
Video-Player per Knopfdruck auslagern (mit onenter)
const player = document.querySelector('#player');
const container = document.querySelector('#player-container');
const button = document.querySelector('#pip-button');
documentPictureInPicture.onenter = ({ window: pipWindow }) => {
container.classList.add('ist-ausgelagert');
// Schließen des Fensters erkennen: Player zurückholen
pipWindow.addEventListener('pagehide', () => {
container.append(player);
container.classList.remove('ist-ausgelagert');
console.log('Bild-in-Bild geschlossen');
});
};
button.addEventListener('click', async () => {
// requestWindow braucht eine Nutzeraktion (hier den Klick)
const pipWindow = await documentPictureInPicture.requestWindow({ width: 480, height: 270 });
pipWindow.document.body.append(player);
});
Listener wieder entfernen
const protokolliereEnter = (event) => {
console.log('enter ausgelöst, Titel:', event.window.document.title);
};
documentPictureInPicture.addEventListener('enter', protokolliereEnter);
// Später, z. B. beim Abbau einer Komponente:
documentPictureInPicture.removeEventListener('enter', protokolliereEnter);
// Alternative: nur ein einziges Mal reagieren
documentPictureInPicture.addEventListener('enter', protokolliereEnter, { once: true });
// Oder den on-Handler zurücksetzen
documentPictureInPicture.onenter = null;
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die Document Picture-in-Picture API ist experimentell und nur in Chromium-Browsern verfügbar (Chrome/Edge ab 116, nur Desktop). Firefox und Safari unterstützen sie nicht. Prüfe deshalb vorher mit
'documentPictureInPicture' in window, ob sie vorhanden ist. - Die API steht nur in sicheren Kontexten (HTTPS) und im Hauptframe zur Verfügung.
requestWindow()braucht eine vorausgegangene Nutzeraktion, sonst wird das Promise mit einem Fehler abgelehnt undenternicht ausgelöst. - Pro Tab ist nur ein Bild-in-Bild-Fenster möglich. Ein erneuter Aufruf von
requestWindow()schließt das alte Fenster und löst für das neue wiederenteraus. - Es gibt kein
leave-Ereignis. Das Schließen erkennst du überpagehideam Bild-in-Bild-Fenster (event.window). - Das neue Fenster startet mit einem leeren Dokument. Stylesheets werden nicht automatisch übernommen, du musst sie selbst kopieren.
- Nicht zu verwechseln mit dem
enterpictureinpicture-Ereignis vonHTMLVideoElement, das zur klassischen Video-Bild-in-Bild-API gehört.