Document Picture-in-Picture API ช่วยให้คุณเปิดหน้าต่างที่แสดงอยู่ด้านบนเสมอซึ่งจะแสดงเนื้อหา HTML ที่กำหนดเองได้ ซึ่งจะขยาย Picture-in-Picture API สำหรับ <video>
ที่มีอยู่ซึ่งอนุญาตให้ใส่เฉพาะองค์ประกอบ HTML <video>
ลงในหน้าต่างภาพซ้อนภาพเท่านั้น
หน้าต่างการแสดงภาพซ้อนภาพใน Document Picture-in-Picture API จะคล้ายกับหน้าต่างต้นทางเดียวกันที่ว่างเปล่าซึ่งเปิดผ่าน window.open()
โดยมีความแตกต่างบางอย่างดังนี้
- หน้าต่างภาพในภาพจะลอยอยู่เหนือหน้าต่างอื่นๆ
- หน้าต่างการแสดงภาพซ้อนภาพจะไม่มีอายุการใช้งานนานกว่าหน้าต่างที่เปิดอยู่
- ไม่สามารถไปยังส่วนต่างๆ ของหน้าต่างการแสดงภาพซ้อนภาพ
- เว็บไซต์ไม่สามารถกำหนดตำแหน่งหน้าต่างของฟีเจอร์ภาพซ้อนภาพได้
สถานะปัจจุบัน
ขั้นตอน | สถานะ |
---|---|
1. สร้างคําอธิบาย | เสร็จสมบูรณ์ |
2. สร้างข้อกำหนดคร่าวๆ เบื้องต้น | กำลังดำเนินการ |
3. รวบรวมความคิดเห็นและทำซ้ำเกี่ยวกับการออกแบบ | กำลังดำเนินการ |
4. ช่วงทดลองใช้จากต้นทาง | เสร็จสมบูรณ์ |
5. เปิด | เสร็จสมบูรณ์ (เดสก์ท็อป) |
กรณีการใช้งาน
วิดีโอเพลเยอร์ที่กำหนดเอง
เว็บไซต์สามารถมอบประสบการณ์การใช้งานวิดีโอแบบ PIP ด้วย Picture-in-Picture API สำหรับ <video>
ที่มีอยู่ แต่มีข้อจำกัดอย่างมาก หน้าต่างการแสดงภาพซ้อนภาพที่มีอยู่ยอมรับอินพุตเพียงไม่กี่รายการและจัดรูปแบบได้จำกัด เมื่อเว็บไซต์มีเอกสารแบบการแสดงภาพซ้อนภาพฉบับสมบูรณ์ เว็บไซต์จึงมีการควบคุมและการป้อนข้อมูลแบบกำหนดเอง (เช่น คำบรรยายวิดีโอ เพลย์ลิสต์ ตัวควบคุมเวลา การกดชอบ และการกดไม่ชอบวิดีโอ) เพื่อปรับปรุงประสบการณ์การใช้งานวิดีโอการแสดงภาพซ้อนภาพของผู้ใช้
การประชุมทางวิดีโอ
เป็นเรื่องปกติที่ผู้ใช้จะออกจากแท็บเบราว์เซอร์ระหว่างเซสชันการประชุมทางวิดีโอด้วยเหตุผลหลายประการ (เช่น นำเสนอแท็บอื่นในการประชุมหรือทำงานหลายอย่างพร้อมกัน) ขณะยังต้องการดูการประชุมอยู่ การแสดงภาพซ้อนภาพจึงถือเป็นกรณีการใช้งานหลัก เราขอย้ำอีกครั้งว่าประสบการณ์ปัจจุบันที่เว็บไซต์วิดีโอคอนเฟอเรนซ์มอบให้ได้ผ่าน Picture-in-Picture API สำหรับ <video>
นั้นมีข้อจำกัดด้านรูปแบบและอินพุต เมื่อใช้เอกสารแบบเต็มในโหมดภาพซ้อนภาพ เว็บไซต์จะรวมสตรีมวิดีโอหลายรายการไว้ในหน้าต่าง PiP เดียวได้อย่างง่ายดายโดยไม่ต้องใช้การแฮ็ก Canvas และสามารถมอบการควบคุมที่กำหนดเอง เช่น การส่งข้อความ การปิดเสียงผู้ใช้รายอื่น หรือยกมือ
ประสิทธิภาพการทำงาน
งานวิจัยแสดงให้เห็นว่าผู้ใช้ต้องการวิธีใหม่ๆ ในการทำงานบนเว็บ เอกสารในโหมดภาพซ้อนภาพช่วยให้เว็บแอปมีความยืดหยุ่นมากขึ้น ไม่ว่าจะเป็นการแก้ไขข้อความ การจดโน้ต รายการงาน การรับส่งข้อความและแชท หรือเครื่องมือออกแบบและพัฒนา เว็บแอปสามารถเข้าถึงเนื้อหาได้ตลอดเวลา
SDK โฆษณา B
พร็อพเพอร์ตี้
documentPictureInPicture.window
- แสดงผลหน้าต่างการแสดงภาพซ้อนภาพปัจจุบัน หากมี ไม่เช่นนั้น ให้แสดงผล
null
เมธอด
documentPictureInPicture.requestWindow(options)
แสดงผลพรอมต์ที่สำเร็จเมื่อเปิดหน้าต่างการแสดงภาพซ้อนภาพ พรอมต์จะปฏิเสธหากมีการเรียกใช้โดยไม่มีท่าทางสัมผัสของผู้ใช้ พจนานุกรม
options
มีสมาชิกต่อไปนี้ซึ่งไม่บังคับwidth
- กำหนดความกว้างเริ่มต้นของหน้าต่างการแสดงภาพซ้อนภาพ
height
- ตั้งค่าความสูงเริ่มต้นของหน้าต่างภาพซ้อนภาพ
disallowReturnToOpener
- ซ่อนปุ่ม "กลับไปยังแท็บ" ในหน้าต่างภาพในภาพหากเป็นจริง โดยค่าเริ่มต้นจะเป็น False
preferInitialWindowPlacement
- เปิดหน้าต่างการแสดงภาพซ้อนภาพในตำแหน่งและขนาดเริ่มต้น หากมี โดยค่าเริ่มต้น ค่านี้จะเป็นเท็จ
เหตุการณ์
documentPictureInPicture.onenter
- เรียกใช้เมื่อ
documentPictureInPicture
เมื่อเปิดหน้าต่างการแสดงภาพซ้อนภาพ
ตัวอย่าง
HTML ต่อไปนี้จะตั้งค่าวิดีโอเพลเยอร์ที่กำหนดเองและองค์ประกอบปุ่มเพื่อเปิดวิดีโอเพลเยอร์ในหน้าต่างการแสดงภาพซ้อนภาพ
<div id="playerContainer">
<div id="player">
<video id="video"></video>
</div>
</div>
<button id="pipButton">Open Picture-in-Picture window</button>
เปิดหน้าต่างการแสดงภาพซ้อนภาพ
JavaScript ต่อไปนี้จะเรียก documentPictureInPicture.requestWindow()
เมื่อผู้ใช้คลิกเพื่อเปิดหน้าต่างการแสดงภาพซ้อนภาพที่ว่างเปล่า พรอมต์ที่แสดงผลจะแสดงผลด้วยออบเจ็กต์ JavaScript ของหน้าต่างภาพซ้อนภาพ ระบบจะย้ายวิดีโอเพลเยอร์ไปยังหน้าต่างนั้นโดยใช้ 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);
});
กำหนดขนาดของหน้าต่างการแสดงภาพซ้อนภาพ
หากต้องการกำหนดขนาดของหน้าต่างการแสดงภาพซ้อนภาพ ให้ตั้งค่าตัวเลือก width
และ height
ของ documentPictureInPicture.requestWindow()
เป็นขนาดหน้าต่างการแสดงภาพซ้อนภาพที่ต้องการ Chrome อาจจำกัดค่าตัวเลือกหากค่ามีขนาดใหญ่หรือเล็กเกินไปที่จะพอดีกับขนาดหน้าต่างที่ใช้งานง่าย
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);
});
ซ่อนปุ่ม "กลับไปที่แท็บ" ของหน้าต่างการแสดงภาพซ้อนภาพ
หากต้องการซ่อนปุ่มในหน้าต่างภาพซ้อนภาพที่อนุญาตให้ผู้ใช้กลับไปที่แท็บที่เปิด ให้ตั้งค่าตัวเลือก disallowReturnToOpener
ของ documentPictureInPicture.requestWindow()
เป็น 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,
});
});
เปิดหน้าต่างการแสดงภาพซ้อนภาพในตำแหน่งและขนาดเริ่มต้น
หากไม่ต้องการนําตําแหน่งหรือขนาดของหน้าต่างภาพซ้อนภาพก่อนหน้ามาใช้ซ้ำ ให้ตั้งค่าตัวเลือก preferInitialWindowPlacement
ของ documentPictureInPicture.requestWindow()
เป็น true
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window in its default position / size.
const pipWindow = await documentPictureInPicture.requestWindow({
preferInitialWindowPlacement: true,
});
});
คัดลอกสไตล์ชีตไปยังหน้าต่างการแสดงภาพซ้อนภาพ
หากต้องการคัดลอกสไตล์ชีต CSS ทั้งหมดจากหน้าต่างต้นทาง ให้วนซ้ำ styleSheets
ที่ลิงก์โดยตรงหรือฝังอยู่ในเอกสาร แล้วนำไปต่อท้ายหน้าต่างการแสดงภาพซ้อนภาพ โปรดทราบว่าการคัดลอกนี้ทำได้เพียงครั้งเดียว
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);
});
จัดการเมื่อหน้าต่างการแสดงภาพซ้อนภาพปิด
ฟังเหตุการณ์ "pagehide"
ของหน้าต่างเพื่อดูว่าเมื่อใดที่หน้าต่างภาพซ้อนภาพปิดลง (เนื่องจากเว็บไซต์เริ่มดำเนินการหรือผู้ใช้ปิดด้วยตนเอง) ตัวแฮนเดิลเหตุการณ์เป็นตําแหน่งที่ดีในการนําองค์ประกอบออกจากหน้าต่างภาพในภาพดังที่แสดงที่นี่
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);
});
});
ปิดหน้าต่างการแสดงภาพซ้อนภาพแบบเป็นโปรแกรมโดยใช้เมธอด close()
// Close the Picture-in-Picture window programmatically.
// The "pagehide" event will fire normally.
pipWindow.close();
ฟังเมื่อเว็บไซต์เข้าสู่การแสดงภาพซ้อนภาพ
ฟังเหตุการณ์ "enter"
ใน documentPictureInPicture
เพื่อดูว่าเมื่อใดที่หน้าต่างภาพซ้อนภาพเปิดขึ้น กิจกรรมนี้มีออบเจ็กต์ window
เพื่อเข้าถึงหน้าต่างภาพซ้อนภาพ
documentPictureInPicture.addEventListener("enter", (event) => {
const pipWindow = event.window;
});
เข้าถึงองค์ประกอบในหน้าต่างการแสดงภาพซ้อนภาพ
เข้าถึงองค์ประกอบในหน้าต่างภาพซ้อนภาพจากออบเจ็กต์ที่ documentPictureInPicture.requestWindow()
แสดง หรือใช้ documentPictureInPicture.window
ตามที่แสดงด้านล่าง
const pipWindow = documentPictureInPicture.window;
if (pipWindow) {
// Mute video playing in the Picture-in-Picture window.
const pipVideo = pipWindow.document.querySelector("#video");
pipVideo.muted = true;
}
จัดการเหตุการณ์จากหน้าต่างการแสดงภาพซ้อนภาพ
สร้างปุ่มและการควบคุม และตอบสนองต่อเหตุการณ์อินพุตของผู้ใช้ เช่น "click"
ตามที่ทําใน JavaScript ตามปกติ
// 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);
ปรับขนาดหน้าต่างการแสดงภาพซ้อนภาพ
ใช้วิธีการปรับขนาดหน้าต่าง resizeBy()
และ resizeTo()
เพื่อปรับขนาดหน้าต่างการแสดงภาพซ้อนภาพ ทั้ง 2 วิธีต้องใช้ท่าทางสัมผัสของผู้ใช้
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()
หน้าต่างเพื่อโฟกัสหน้าต่างที่เปิดอยู่จากหน้าต่างการแสดงภาพซ้อนภาพ วิธีนี้ต้องใช้ท่าทางสัมผัสของผู้ใช้
const returnToTabButton = pipWindow.document.createElement("button");
returnToTabButton.textContent = "Return to opener tab";
returnToTabButton.addEventListener("click", () => {
window.focus();
});
pipWindow.document.body.append(returnToTabButton);
โหมดการแสดงภาพซ้อนภาพ CSS
ใช้โหมดการแสดงผล picture-in-picture
ของ CSS เพื่อเขียนกฎ CSS ที่เฉพาะเจาะจงซึ่งจะใช้ก็ต่อเมื่อเว็บแอป (บางส่วน) แสดงในโหมดภาพในภาพเท่านั้น
@media all and (display-mode: picture-in-picture) {
body {
margin: 0;
}
h1 {
font-size: 0.8em;
}
}
การตรวจหาองค์ประกอบ
หากต้องการตรวจสอบว่าระบบรองรับ Document Picture-in-Picture API หรือไม่ ให้ใช้คำสั่งต่อไปนี้
if ('documentPictureInPicture' in window) {
// The Document Picture-in-Picture API is supported.
}
เดโม
วิดีโอเพลเยอร์ VideoJS
คุณสามารถเล่นกับการสาธิตโปรแกรมเล่น VideoJS ของ Document Picture-in-Picture API อย่าลืมตรวจสอบซอร์สโค้ด
Pomodoro
นอกจากนี้ Tomodoro ซึ่งเป็นเว็บแอปของ Pomodoro ยังใช้ประโยชน์จาก Document Picture-in-Picture API ด้วยเมื่อมีให้บริการ ดูคำขอดึงข้อมูล GitHub
แชร์ความคิดเห็น
แจ้งปัญหาใน GitHub พร้อมคําแนะนําและคําถาม