De Document Picture-in-Picture API maakt het mogelijk om een altijd-bovenaan venster te openen dat kan worden gevuld met willekeurige HTML-inhoud. Het is een uitbreiding van de bestaande Picture-in-Picture API voor <video>
, die alleen het plaatsen van een HTML <video>
-element in een Picture-in-Picture-venster toestaat.
Het Picture-in-Picture-venster in de Document Picture-in-Picture API is vergelijkbaar met een leeg venster met dezelfde oorsprong dat wordt geopend via window.open()
, met enkele verschillen:
- Het Picture-in-Picture-venster zweeft bovenop andere vensters.
- Het Picture-in-Picture-venster overleeft het openingsvenster nooit.
- Er kan niet door het Picture-in-Picture-venster worden genavigeerd.
- De positie van het Picture-in-Picture-venster kan niet door de website worden ingesteld.

Huidige status
Stap | Status |
---|---|
1. Maak een uitleg | Compleet |
2. Maak een eerste ontwerp van de specificatie | In uitvoering |
3. Verzamel feedback en herhaal het ontwerp | In uitvoering |
4. Oorsprongsproef | Compleet |
5. Lancering | Compleet (Bureaublad) |
Gebruiksscenario's
Aangepaste videospeler
Een website kan een Picture-in-Picture-video-ervaring bieden met de bestaande Picture-in-Picture API voor <video>
, maar deze is zeer beperkt. Het bestaande Picture-in-Picture-venster accepteert weinig invoer en heeft beperkte mogelijkheden voor de styling ervan. Met een volledig document in Picture-in-Picture kan de website aangepaste bedieningselementen en invoer bieden (bijvoorbeeld ondertitels , afspeellijsten, een tijdscrubber, het leuk vinden en niet leuk vinden van video's) om de Picture-in-Picture-video-ervaring van de gebruiker te verbeteren.
Videoconferenties
Het komt vaak voor dat gebruikers tijdens een videoconferentiesessie om verschillende redenen het browsertabblad verlaten (bijvoorbeeld om een ander tabblad aan het gesprek te presenteren of om te multitasken), terwijl ze het gesprek toch willen zien. Dit is dan ook een uitstekende use case voor Picture-in-Picture. Nogmaals, de huidige ervaring die een videoconferentiewebsite kan bieden via de Picture-in-Picture API voor <video>
is beperkt in stijl en invoer. Met een volledig Document in Picture-in-Picture kan de website eenvoudig meerdere videostreams combineren in één PiP-venster zonder dat er canvas-hacks nodig zijn en zonder aangepaste bedieningselementen zoals het verzenden van een bericht, het dempen van een andere gebruiker of het opsteken van een hand.
Productiviteit
Onderzoek heeft aangetoond dat gebruikers meer mogelijkheden nodig hebben om productief te zijn op het web. Document in Picture-in-Picture geeft webapps de flexibiliteit om meer te bereiken. Of het nu gaat om tekstbewerking, notities maken, takenlijsten, berichten en chatten, of ontwerp- en ontwikkeltools, webapps kunnen hun content nu altijd toegankelijk houden.
Interface
Eigenschappen
-
documentPictureInPicture.window
- Retourneert het huidige Picture-in-Picture-venster (indien aanwezig). Anders wordt
null
geretourneerd.
Methoden
-
documentPictureInPicture.requestWindow(options)
Retourneert een belofte die wordt opgelost wanneer een Picture-in-Picture-venster wordt geopend. De belofte wordt afgewezen als deze wordt aangeroepen zonder een gebruikersgebaar. Het
options
bevat de volgende optionele leden:-
width
- Stelt de beginbreedte van het Picture-in-Picture-venster in.
-
height
- Stelt de beginhoogte van het Picture-in-Picture-venster in.
-
disallowReturnToOpener
- Verbergt de knop 'Terug naar tabblad' in het Picture-in-Picture-venster indien 'true'. Standaard is dit 'false'.
-
preferInitialWindowPlacement
- Open het Picture-in-Picture-venster in de standaardpositie en -grootte als 'true' is ingeschakeld. Standaard is dit 'false'.
-
Evenementen
-
documentPictureInPicture.onenter
- Wordt geactiveerd op
documentPictureInPicture
wanneer een Picture-in-Picture-venster wordt geopend.
Voorbeelden
Met de volgende HTML-code worden een aangepaste videospeler en een knopelement ingesteld om de videospeler te openen in een Picture-in-Picture-venster.
<div id="playerContainer">
<div id="player">
<video id="video"></video>
</div>
</div>
<button id="pipButton">Open Picture-in-Picture window</button>
Open een Picture-in-Picture-venster
De volgende JavaScript-code roept documentPictureInPicture.requestWindow()
aan wanneer de gebruiker op de knop klikt om een leeg Picture-in-Picture-venster te openen. De geretourneerde promise wordt omgezet naar een Picture-in-Picture-venster JavaScript-object. De videospeler wordt naar dat venster verplaatst met append()
.
pipButton.addEventListener('click', async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window.
const pipWindow = await documentPictureInPicture.requestWindow();
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
});
De grootte van het Picture-in-Picture-venster instellen
Om de grootte van het Picture-in-Picture-venster in te stellen, stelt u de width
en height
van documentPictureInPicture.requestWindow()
in op de gewenste Picture-in-Picture-venstergrootte. Chrome kan de optiewaarden beperken als ze te groot of te klein zijn voor een gebruiksvriendelijk vensterformaat.
pipButton.addEventListener("click", async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window whose size is
// the same as the player's.
const pipWindow = await documentPictureInPicture.requestWindow({
width: player.clientWidth,
height: player.clientHeight,
});
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
});
Verberg de knop 'Terug naar tabblad' van het Picture-in-Picture-venster
Om de knop in het Picture-in-Picture-venster te verbergen waarmee de gebruiker kan teruggaan naar het tabblad van de opener, stelt u de optie disallowReturnToOpener
van documentPictureInPicture.requestWindow()
in op true
.
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window which hides the "back to tab" button.
const pipWindow = await documentPictureInPicture.requestWindow({
disallowReturnToOpener: true,
});
});
Open het Picture-in-Picture-venster in de standaardpositie en -grootte
Als u de positie of grootte van het vorige Picture-in-Picture-venster niet opnieuw wilt gebruiken, stelt u de optie preferInitialWindowPlacement
van documentPictureInPicture.requestWindow()
in op true
.
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window in its default position / size.
const pipWindow = await documentPictureInPicture.requestWindow({
preferInitialWindowPlacement: true,
});
});
Stijlbladen kopiëren naar het Picture-in-Picture-venster
Om alle CSS-stijlbladen uit het oorspronkelijke venster te kopiëren, doorloopt u styleSheets
die expliciet aan het document zijn gekoppeld of erin zijn ingesloten en voegt u ze toe aan het Picture-in-Picture-venster. Let op: dit is een eenmalige kopie.
pipButton.addEventListener("click", async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window.
const pipWindow = await documentPictureInPicture.requestWindow();
// Copy style sheets over from the initial document
// so that the player looks the same.
[...document.styleSheets].forEach((styleSheet) => {
try {
const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join('');
const style = document.createElement('style');
style.textContent = cssRules;
pipWindow.document.head.appendChild(style);
} catch (e) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = styleSheet.type;
link.media = styleSheet.media;
link.href = styleSheet.href;
pipWindow.document.head.appendChild(link);
}
});
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
});
Handgreep wanneer het Picture-in-Picture-venster sluit
Luister naar de "pagehide"
-gebeurtenis van het venster om te weten wanneer het Picture-in-Picture-venster wordt gesloten (omdat de website het heeft geïnitieerd of de gebruiker het handmatig heeft gesloten). De gebeurtenishandler is een goede manier om de elementen weer uit het Picture-in-Picture-venster te halen, zoals hier wordt getoond.
pipButton.addEventListener("click", async () => {
const player = document.querySelector("#player");
// Open a Picture-in-Picture window.
const pipWindow = await documentPictureInPicture.requestWindow();
// Move the player to the Picture-in-Picture window.
pipWindow.document.body.append(player);
// Move the player back when the Picture-in-Picture window closes.
pipWindow.addEventListener("pagehide", (event) => {
const playerContainer = document.querySelector("#playerContainer");
const pipPlayer = event.target.querySelector("#player");
playerContainer.append(pipPlayer);
});
});
Sluit het Picture-in-Picture-venster programmatisch met behulp van de close()
methode.
// Close the Picture-in-Picture window programmatically.
// The "pagehide" event will fire normally.
pipWindow.close();
Luister wanneer de website Picture-in-Picture invoert
Luister naar de "enter"
-gebeurtenis op documentPictureInPicture
om te weten wanneer een Picture-in-Picture-venster wordt geopend. De gebeurtenis bevat een window
om toegang te krijgen tot het Picture-in-Picture-venster.
documentPictureInPicture.addEventListener("enter", (event) => {
const pipWindow = event.window;
});
Toegang tot elementen in het Picture-in-Picture-venster
U kunt toegang krijgen tot elementen in het Picture-in-Picture-venster via het object dat wordt geretourneerd door documentPictureInPicture.requestWindow()
of met documentPictureInPicture.window
, zoals hieronder wordt weergegeven.
const pipWindow = documentPictureInPicture.window;
if (pipWindow) {
// Mute video playing in the Picture-in-Picture window.
const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.muted = true;
}
Gebeurtenissen verwerken vanuit het Picture-in-Picture-venster
Maak knoppen en besturingselementen en reageer op invoergebeurtenissen van de gebruiker, zoals "click"
, zoals u dat normaal gesproken in JavaScript zou doen.
// Add a "mute" button to the Picture-in-Picture window.
const pipMuteButton = pipWindow.document.createElement("button");
pipMuteButton.textContent = "Mute";
pipMuteButton.addEventListener("click", () => {
const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.muted = true;
});
pipWindow.document.body.append(pipMuteButton);
Het formaat van het Picture-in-Picture-venster wijzigen
Gebruik de venstermethoden resizeBy()
en resizeTo()
om het formaat van het Picture-in-Picture-venster aan te passen. Beide methoden vereisen een gebruikersgebaar.
const resizeButton = pipWindow.document.createElement('button');
resizeButton.textContent = 'Resize';
resizeButton.addEventListener('click', () => {
// Expand the Picture-in-Picture window's width by 20px and height by 30px.
pipWindow.resizeBy(20, 30);
});
pipWindow.document.body.append(resizeButton);
Focus het openervenster
Gebruik de focus()
Window-methode om het geopende venster te focussen vanuit het Picture-in-Picture-venster. Deze methode vereist een gebruikersgebaar.
const returnToTabButton = pipWindow.document.createElement("button");
returnToTabButton.textContent = "Return to opener tab";
returnToTabButton.addEventListener("click", () => {
window.focus();
});
pipWindow.document.body.append(returnToTabButton);
CSS-beeld-in-beeld-weergavemodus
Gebruik de picture-in-picture
weergavemodus van CSS om specifieke CSS-regels te schrijven die alleen worden toegepast wanneer (een deel van) de web-app wordt weergegeven in de Picture-in-Picture-modus.
@media all and (display-mode: picture-in-picture) {
body {
margin: 0;
}
h1 {
font-size: 0.8em;
}
}
Functiedetectie
Om te controleren of de Document Picture-in-Picture API wordt ondersteund, gebruikt u:
if ('documentPictureInPicture' in window) {
// The Document Picture-in-Picture API is supported.
}
Demo's
VideoJS-speler
U kunt spelen met de Document Picture-in-Picture API VideoJS-spelerdemo .
Pomodoro
Tomodoro , een Pomodoro-webapp, maakt ook gebruik van de Document Picture-in-Picture API zodra deze beschikbaar is. Zie hun GitHub pull request .

Deel uw feedback
Meld problemen op GitHub met suggesties en vragen.