Signatur
Beschreibung
window.documentPictureInPicture ist der Einstieg in die Document Picture-in-Picture API. Mit der klassischen Picture-in-Picture-API (HTMLVideoElement.requestPictureInPicture()) lässt sich nur ein einzelnes <video>-Element auslagern. Diese Eigenschaft liefert dagegen ein DocumentPictureInPicture-Objekt, mit dem du ein schwebendes Fenster öffnest, das dauerhaft über anderen Fenstern bleibt und beliebiges DOM enthalten kann: eigene Video-Steuerelemente, Videokonferenz-Kacheln, Timer, Notizen oder Chats.
Das zurückgegebene Objekt bietet die Methode requestWindow(options), die ein Promise<Window> liefert. Dazu kommen die Eigenschaft window, die auf das gerade offene PiP-Fenster zeigt (oder null, wenn keins offen ist), und das Ereignis enter, das beim Öffnen feuert. In das neue Fenster verschiebst du vorhandene Elemente per append(). Stylesheets werden nicht automatisch übernommen, die musst du selbst kopieren.
Die Eigenschaft gibt es nur in sicheren Kontexten (HTTPS oder localhost) und nur im obersten Fenster. requestWindow() braucht außerdem eine transiente Nutzeraktivierung, du musst es also z. B. in einem Klick-Handler aufrufen. Pro Tab kann immer nur ein PiP-Fenster offen sein.
Rückgabewert
DocumentPictureInPicture-Singleton des aktuellen Browsing-Kontexts, mit requestWindow(), window und dem Ereignis enter. In Browsern ohne Unterstützung ist die Eigenschaft nicht vorhanden (undefined).Beispiele
Unterstützung prüfen
const supported = 'documentPictureInPicture' in window;
console.log(supported ? 'Document PiP verfügbar' : 'Nicht unterstützt');
// Beispielsweise einen Button nur dann einblenden
document.querySelector('#pip-btn').hidden = !supported;
Player in ein PiP-Fenster verschieben und Styles kopieren
const player = document.querySelector('#player');
const container = document.querySelector('#player-container');
document.querySelector('#pip-btn').addEventListener('click', async () => {
// Muss per Nutzeraktion ausgelöst werden
const pipWindow = await documentPictureInPicture.requestWindow({
width: 480,
height: 270
});
// Stylesheets übernehmen
for (const sheet of document.styleSheets) {
try {
const css = [...sheet.cssRules].map((r) => r.cssText).join('');
const style = document.createElement('style');
style.textContent = css;
pipWindow.document.head.append(style);
} catch {
// Fremd-Stylesheet (CORS): als <link> einbinden
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = sheet.href;
pipWindow.document.head.append(link);
}
}
pipWindow.document.body.append(player);
// Beim Schließen zurück ins Hauptdokument verschieben
pipWindow.addEventListener('pagehide', () => {
container.append(player);
});
});
Auf das enter-Ereignis reagieren und offenes Fenster schließen
documentPictureInPicture.addEventListener('enter', (event) => {
const pipWin = event.window;
console.log('PiP geöffnet:', pipWin.innerWidth, 'x', pipWin.innerHeight);
});
document.querySelector('#close-pip').addEventListener('click', () => {
// window ist null, wenn gerade kein PiP-Fenster offen ist
documentPictureInPicture.window?.close();
});
// Wichtig · Fallstricke
- Kompatibilität: Experimentell, bisher nur in Chromium-Browsern (Chrome/Edge ab 116, nur Desktop). Firefox und Safari unterstützen die API nicht. Prüfe deshalb immer vorher mit
'documentPictureInPicture' in window. - Nur in sicheren Kontexten (HTTPS). In iframes nicht verfügbar, dort ist
requestWindow()nur im Top-Level-Dokument erlaubt. requestWindow()ohne Nutzeraktivierung wird mitNotAllowedErrorabgelehnt. Wird es aus einem PiP-Fenster heraus aufgerufen, ist das ebenfalls ein Fehler.- CSS wird nicht automatisch übernommen. Kopiere Stylesheets selbst oder wende sie per
adoptedStyleSheetsan. - Verschobene Elemente behalten ihre Event-Listener.
documentundwindowim Code beziehen sich aber weiterhin auf das Hauptfenster. Nutze stattdessenelement.ownerDocument. - Beim Schließen des PiP-Fensters gehen die Elemente darin verloren. Hole sie im
pagehide-Ereignis zurück ins Hauptdokument. - Größe und Position bestimmt letztlich der Browser.
widthundheightsind nur Wünsche.window.resizeTo()funktioniert im PiP-Fenster nur mit Nutzeraktivierung.