API การแสดงภาพซ้อนภาพของเอกสารช่วยให้เปิดหน้าต่างที่อยู่ด้านบนสุดเสมอซึ่งสามารถแสดงเนื้อหา HTML ที่กำหนดเองได้ โดยจะขยาย Picture-in-Picture API สำหรับ <video> ที่อนุญาตให้วางเฉพาะองค์ประกอบ HTML <video> ลงในหน้าต่างการแสดงภาพซ้อนภาพ
หน้าต่างการแสดงภาพซ้อนภาพใน Document Picture-in-Picture API จะคล้ายกับหน้าต่างแบบเดียวกันที่ว่างเปล่าซึ่งเปิดผ่าน window.open() โดยมีความแตกต่างบางประการดังนี้
- หน้าต่างการแสดงภาพซ้อนภาพจะลอยอยู่เหนือหน้าต่างอื่นๆ
- หน้าต่างการแสดงภาพซ้อนภาพจะไม่มีวันอยู่ได้นานกว่าหน้าต่างที่เปิด
- คุณไม่สามารถไปยังส่วนต่างๆ ของหน้าต่างการแสดงภาพซ้อนภาพได้
- เว็บไซต์ไม่สามารถกำหนดตำแหน่งของหน้าต่างการแสดงภาพซ้อนภาพได้
 
  สถานะปัจจุบัน
| ขั้นตอน | สถานะ | 
|---|---|
| 1. สร้างวิดีโออธิบาย | เสร็จสมบูรณ์ | 
| 2. สร้างร่างข้อกำหนดเบื้องต้น | กำลังดำเนินการ | 
| 3. รวบรวมความคิดเห็นและทำซ้ำการออกแบบ | กำลังดำเนินการ | 
| 4. ช่วงทดลองใช้จากต้นทาง | เสร็จสมบูรณ์ | 
| 5. เปิดตัว | เสร็จสมบูรณ์ (เดสก์ท็อป) | 
กรณีการใช้งาน
วิดีโอเพลเยอร์ที่กำหนดเอง
เว็บไซต์สามารถมอบประสบการณ์การใช้งานวิดีโอแบบ Picture-in-Picture ด้วย Picture-in-Picture API ที่มีอยู่สำหรับ <video> แต่ก็มีข้อจำกัดอย่างมาก หน้าต่างการแสดงภาพซ้อนภาพที่มีอยู่รับอินพุตได้เพียงเล็กน้อย และมีความสามารถในการจัดรูปแบบจำกัด เมื่อใช้เอกสารแบบเต็มในการแสดงภาพซ้อนภาพ เว็บไซต์จะสามารถให้การควบคุมและอินพุตที่กำหนดเอง (เช่น คำบรรยายแทนเสียง เพลย์ลิสต์ แถบเลื่อนเวลา การกดชอบและไม่ชอบวิดีโอ) เพื่อปรับปรุงประสบการณ์การใช้งานวิดีโอแบบแสดงภาพซ้อนภาพของผู้ใช้
การประชุมทางวิดีโอ
ผู้ใช้มักจะออกจากแท็บเบราว์เซอร์ระหว่างเซสชันการประชุมทางวิดีโอด้วยเหตุผลต่างๆ (เช่น การนำเสนอแท็บอื่นในการโทรหรือการทำงานหลายอย่างพร้อมกัน) ในขณะที่ยังต้องการดูการโทรอยู่ ดังนั้นการแสดงภาพซ้อนภาพจึงเป็นกรณีการใช้งานที่สำคัญ อีกครั้งที่ประสบการณ์การใช้งานปัจจุบันที่เว็บไซต์การประชุมทางวิดีโอสามารถมอบให้ผ่าน Picture-in-Picture API สำหรับ <video> มีข้อจำกัดด้านสไตล์และอินพุต เมื่อใช้เอกสารแบบเต็มในโหมดการแสดงภาพซ้อนภาพ เว็บไซต์จะรวมสตรีมวิดีโอหลายรายการไว้ในหน้าต่าง PiP เดียวได้อย่างง่ายดายโดยไม่ต้องใช้แฮ็ก Canvas และมีตัวควบคุมที่กำหนดเอง เช่น การส่งข้อความ การปิดเสียงผู้ใช้รายอื่น หรือการยกมือ
ประสิทธิภาพการทำงาน
งานวิจัยแสดงให้เห็นว่าผู้ใช้ต้องการวิธีเพิ่มเติมในการทำงานบนเว็บอย่างมีประสิทธิภาพ เอกสารในการแสดงภาพซ้อนภาพช่วยให้เว็บแอปมีความยืดหยุ่นในการทำงานต่างๆ มากขึ้น ไม่ว่าจะเป็นการแก้ไขข้อความ การจดบันทึก รายการงาน การรับส่งข้อความและแชท หรือเครื่องมือออกแบบและพัฒนา เว็บแอปก็สามารถทำให้เนื้อหาเข้าถึงได้เสมอ
SDK โฆษณา B
พร็อพเพอร์ตี้
- documentPictureInPicture.window
- แสดงหน้าต่างการแสดงภาพซ้อนภาพปัจจุบัน (หากมี) หากไม่ จะแสดงผล null
เมธอด
- documentPictureInPicture.requestWindow(options)
- แสดงผล Promise ที่จะทำงานเมื่อเปิดหน้าต่างการแสดงภาพซ้อนภาพ Promise จะปฏิเสธหากมีการเรียกใช้โดยไม่มีท่าทางของผู้ใช้ พจนานุกรม - optionsมีสมาชิกต่อไปนี้ซึ่งระบุหรือไม่ก็ได้- width
- กำหนดความกว้างเริ่มต้นของหน้าต่างการแสดงภาพซ้อนภาพ
- height
- กำหนดความสูงเริ่มต้นของหน้าต่างการแสดงภาพซ้อนภาพ
- disallowReturnToOpener
- ซ่อนปุ่ม "กลับไปที่แท็บ" ในหน้าต่างภาพในภาพหากเป็นจริง โดยค่าเริ่มต้นจะเป็นเท็จ
- 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() เมื่อผู้ใช้คลิกปุ่มเพื่อเปิดหน้าต่างภาพซ้อนภาพที่ว่างเปล่า Promise ที่แสดงผลจะได้รับการแก้ไขด้วยออบเจ็กต์ 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() ของ Window เพื่อปรับขนาดหน้าต่างการแสดงภาพซ้อนภาพ ทั้ง 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() Window เพื่อโฟกัสหน้าต่างที่เปิดจากหน้าต่างการแสดงภาพซ้อนภาพ วิธีนี้ต้องใช้ท่าทางของผู้ใช้
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
คุณสามารถทดลองใช้ Document Picture-in-Picture API ได้ในการสาธิตโปรแกรมเล่น VideoJS
Pomodoro
Tomodoro ซึ่งเป็นเว็บแอป Pomodoro ยังใช้ประโยชน์จาก Document Picture-in-Picture API เมื่อพร้อมใช้งานด้วย ดูคำขอดึงข้อมูลใน GitHub
 
  แชร์ความคิดเห็น
แจ้งปัญหาใน GitHub พร้อมคำแนะนำและคำถาม
