Document Picture-in-Picture API cho phép mở một cửa sổ luôn ở trên cùng và có thể chứa nội dung HTML tuỳ ý. API này mở rộng API Hình trong hình hiện có cho <video>. API này chỉ cho phép đặt một phần tử HTML <video> vào cửa sổ Hình trong hình (PiP).
Cửa sổ Hình trong hình trong Document Picture-in-Picture API tương tự như một cửa sổ trống có cùng nguồn gốc được mở bằng window.open(), với một số điểm khác biệt:
- Cửa sổ Hình trong hình sẽ nổi lên trên các cửa sổ khác.
- Cửa sổ Hình trong hình không bao giờ tồn tại lâu hơn cửa sổ mở.
- Bạn không thể di chuyển cửa sổ Hình trong hình.
- Trang web không thể đặt vị trí của cửa sổ Hình trong hình.
Trạng thái
| Bước | Trạng thái |
|---|---|
| 1. Tạo video giải thích | Hoàn tất |
| 2. Tạo bản nháp ban đầu của quy cách | Đang tiến hành |
| 3. Thu thập ý kiến phản hồi và lặp lại quy trình thiết kế | Đang tiến hành |
| 4. Bản dùng thử theo nguyên gốc | Hoàn tất |
| 5. Chạy | Hoàn tất (Máy tính) |
Trường hợp sử dụng
Bạn có thể sử dụng API này theo nhiều cách, bao gồm cả trình phát video tuỳ chỉnh, hội nghị truyền hình và các ứng dụng năng suất.
Trình phát video tuỳ chỉnh
Một trang web có thể cung cấp trải nghiệm video ở chế độ Hình trong hình bằng API Hình trong hình hiện có cho <video>, tuy nhiên, API này có rất nhiều hạn chế. Cửa sổ PiP hiện tại chấp nhận một số ít dữ liệu đầu vào và có khả năng hạn chế trong việc tạo kiểu cho các dữ liệu đó. Với một Tài liệu đầy đủ ở chế độ Hình trong hình, trang web có thể cung cấp các chế độ kiểm soát và thông tin đầu vào tuỳ chỉnh (ví dụ: phụ đề, danh sách phát, thanh tua thời gian, thích và không thích video) để cải thiện trải nghiệm xem video ở chế độ PiP của người dùng.
Hội nghị truyền hình
Người dùng thường tạm thời rời khỏi thẻ trình duyệt trong phiên hội nghị truyền hình, chẳng hạn như khi trình bày từ một thẻ khác cho cuộc gọi, ghi chú hoặc các hoạt động đa nhiệm khác. Tuy nhiên, trong hầu hết các trường hợp, người dùng vẫn muốn xem cuộc gọi, do đó, đây là một trường hợp sử dụng lý tưởng cho chế độ Hình trong hình. Một lần nữa, trải nghiệm hiện tại mà một trang web hội nghị truyền hình có thể cung cấp bằng API chế độ Hình trong hình cho <video> bị hạn chế về kiểu dáng và phương thức nhập. Với một Tài liệu đầy đủ ở chế độ Hình trong hình, trang web có thể dễ dàng kết hợp nhiều luồng video vào một cửa sổ PiP duy nhất mà không cần dựa vào các giải pháp tạm thời cho canvas và cung cấp các chế độ điều khiển tuỳ chỉnh, chẳng hạn như gửi tin nhắn, tắt tiếng người dùng khác hoặc giơ tay.
Năng suất
Nghiên cứu cho thấy người dùng cần nhiều cách hơn để làm việc hiệu quả trên web. Tính năng Tài liệu ở chế độ Hình trong hình giúp các ứng dụng web linh hoạt hơn để hoàn thành nhiều việc hơn. Cho dù là chỉnh sửa văn bản, ghi chú, danh sách việc cần làm, nhắn tin và trò chuyện hay các công cụ thiết kế và phát triển, các ứng dụng web hiện có thể giúp nội dung của bạn luôn dễ truy cập.
Giao diện
Thuộc tính
documentPictureInPicture.window- Trả về cửa sổ Hình trong hình hiện tại (nếu có). Nếu không, hàm này sẽ trả về
null.
Phương thức
documentPictureInPicture.requestWindow(options)Trả về một promise sẽ phân giải khi cửa sổ Hình trong hình được mở. Lệnh hứa từ chối nếu được gọi mà không có cử chỉ của người dùng. Từ điển
optionschứa các thành phần không bắt buộc sau:width- Đặt chiều rộng ban đầu của cửa sổ Hình trong hình.
height- Đặt chiều cao ban đầu của cửa sổ Hình trong hình.
disallowReturnToOpener- Ẩn nút "quay lại thẻ" trong cửa sổ Hình trong hình nếu đúng. Theo mặc định, giá trị này là false.
preferInitialWindowPlacement- Mở cửa sổ Hình trong hình ở vị trí và kích thước mặc định nếu đúng. Theo mặc định, giá trị này là false.
Sự kiện
documentPictureInPicture.onenter- Được kích hoạt trên
documentPictureInPicturekhi cửa sổ Hình trong hình được mở.
Ví dụ
HTML sau đây thiết lập một trình phát video tuỳ chỉnh và một phần tử nút để mở trình phát video trong cửa sổ Hình trong hình.
<div id="playerContainer">
<div id="player">
<video id="video"></video>
</div>
</div>
<button id="pipButton">Open Picture-in-Picture window</button>
Mở cửa sổ Hình trong hình
JavaScript sau đây gọi documentPictureInPicture.requestWindow() khi người dùng nhấp vào nút để mở một cửa sổ trống ở chế độ Hình trong hình. Lời hứa được trả về sẽ phân giải bằng một đối tượng JavaScript của cửa sổ Hình trong hình. Trình phát video sẽ được di chuyển đến cửa sổ đó bằng cách sử dụng 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);
});
Đặt kích thước của cửa sổ Hình trong hình
Để đặt kích thước cho cửa sổ Hình trong hình, hãy đặt các lựa chọn width và height của documentPictureInPicture.requestWindow() thành kích thước cửa sổ PiP lý tưởng. Chrome có thể giảm các giá trị lựa chọn nếu chúng quá lớn hoặc quá nhỏ để phù hợp với kích thước cửa sổ thân thiện với người dùng.
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);
});
Ẩn nút "quay lại thẻ" trong cửa sổ hình trong hình
Để ẩn nút trong cửa sổ Hình trong hình cho phép người dùng quay lại thẻ trình phát, hãy đặt lựa chọn disallowReturnToOpener của documentPictureInPicture.requestWindow() thành 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,
});
});
Mở chế độ xem trong cửa sổ nhỏ ở vị trí và kích thước mặc định
Để không dùng lại vị trí hoặc kích thước của cửa sổ Hình trong hình trước đó, hãy đặt lựa chọn preferInitialWindowPlacement của documentPictureInPicture.requestWindow() thành true.
pipButton.addEventListener("click", async () => {
// Open a Picture-in-Picture window in its default position / size.
const pipWindow = await documentPictureInPicture.requestWindow({
preferInitialWindowPlacement: true,
});
});
Sao chép bảng định kiểu vào PiP
Để sao chép tất cả các biểu định kiểu CSS từ cửa sổ gốc, hãy lặp lại styleSheets được liên kết rõ ràng vào hoặc được nhúng trong tài liệu và nối chúng vào cửa sổ Hình trong hình. Xin lưu ý rằng đây là bản sao được tạo một lần.
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);
});
Xử lý khi cửa sổ PiP đóng
Theo dõi sự kiện "pagehide" của cửa sổ để biết thời điểm cửa sổ PiP bị đóng (do trang web khởi tạo hoặc người dùng đóng theo cách thủ công). Trình xử lý sự kiện là nơi phù hợp để lấy các phần tử ra khỏi cửa sổ Hình trong hình như minh hoạ ở đây.
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);
});
});
Đóng cửa sổ Hình trong hình theo phương thức lập trình bằng cách sử dụng phương thức close().
// Close the Picture-in-Picture window programmatically.
// The "pagehide" event will fire normally.
pipWindow.close();
Nghe khi trang web chuyển sang chế độ PiP
Theo dõi sự kiện "enter" trên documentPictureInPicture để biết thời điểm cửa sổ Hình trong hình được mở. Sự kiện này chứa một đối tượng window để truy cập vào cửa sổ Hình trong hình.
documentPictureInPicture.addEventListener("enter", (event) => {
const pipWindow = event.window;
});
Truy cập các phần tử trong cửa sổ hình trong hình
Truy cập vào các phần tử trong cửa sổ PiP từ đối tượng do documentPictureInPicture.requestWindow() trả về hoặc bằng 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;
}
Xử lý các sự kiện từ cửa sổ PiP
Tạo các nút và chế độ điều khiển, đồng thời phản hồi các sự kiện đầu vào của người dùng (chẳng hạn như "click"), như thường lệ trong 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);
Đổi kích thước cửa sổ PiP
Sử dụng các phương thức resizeBy() và resizeTo() của Cửa sổ để đổi kích thước cửa sổ Hình trong hình. Cả hai phương thức đều yêu cầu người dùng thực hiện một cử chỉ.
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);
Lấy tiêu điểm ở cửa sổ trình phát
Sử dụng phương thức focus() Window để lấy tiêu điểm cửa sổ trình mở từ cửa sổ Hình trong hình.
Phương thức này yêu cầu một cử chỉ của người dùng.
const returnToTabButton = pipWindow.document.createElement("button");
returnToTabButton.textContent = "Return to opener tab";
returnToTabButton.addEventListener("click", () => {
window.focus();
});
pipWindow.document.body.append(returnToTabButton);
Chế độ hiển thị CSS PiP
Sử dụng chế độ hiển thị CSS picture-in-picture để viết các quy tắc CSS cụ thể chỉ được áp dụng khi (một phần của) ứng dụng web xuất hiện ở chế độ Hình trong hình.
@media all and (display-mode: picture-in-picture) {
body {
margin: 0;
}
h1 {
font-size: 0.8em;
}
}
Phát hiện đối tượng
Để kiểm tra xem API Chế độ hình trong hình cho tài liệu có được hỗ trợ hay không, hãy sử dụng:
if ('documentPictureInPicture' in window) {
// The Document Picture-in-Picture API is supported.
}
Bản minh hoạ
- Trình phát VideoJS: Phát bằng API Hình trong hình của tài liệu Bản minh hoạ trình phát VideoJS.
- Tomodoro, một ứng dụng web pomodoro, tận dụng API Hình trong hình của tài liệu khi có thể. Xem yêu cầu kéo trên GitHub của họ.
Chia sẻ ý kiến phản hồi của bạn
Báo cáo vấn đề trên GitHub kèm theo đề xuất và câu hỏi.