<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【資訊】1795- Chrome 116:網(wǎng)頁畫中畫 API 來了!

          共 8374字,需瀏覽 17分鐘

           ·

          2023-09-06 17:41

          Chrome 116 剛剛發(fā)布了正式版本,其中比較值得關(guān)注的新增功能就是網(wǎng)頁的畫中畫 API 了(Document Picture in Picture API )。

          簡介

          畫中畫 API 可以打開一個始終位于當(dāng)前網(wǎng)頁頂部的窗口,這個窗口可以填充任意的 HTML 內(nèi)容。它擴展了現(xiàn)有的 Picture-in-Picture API for <video> (其只允許將 <video> 元素放入畫中畫窗口中)。

          通過 Document Picture-in-Picture API 創(chuàng)建的 Picture-in-Picture 窗口其實很類似于通過 window.open() 打開的空白的同源窗口,但也存在一些差異:

          • 畫中畫窗口永遠(yuǎn)會浮動在其他窗口之上。
          • 當(dāng)前窗口關(guān)閉后會立即關(guān)閉打開的畫中畫窗口
          • 無法通過地址導(dǎo)航到畫中畫窗口。
          • 畫中畫窗口的位置無法由網(wǎng)站設(shè)置。

          使用場景

          這個 API 還是有挺多實用場景的,首先我們還是可以用它來實現(xiàn)自定義視頻播放器,雖然現(xiàn)有的 Picture-in-Picture API for <video> 也可以實現(xiàn),但是效果非常有限(參數(shù)少,樣式設(shè)置靈活)?,F(xiàn)在通過新的畫中畫 API,網(wǎng)站可以提供一些自定義組件和參數(shù)(例如字幕、播放列表、時間控制、喜歡和不喜歡的視頻),來改善用戶的畫中畫視頻體驗。另外我們還可以用它來實現(xiàn)一個體驗非常好的網(wǎng)頁視頻會議功能等等。

          用法

          屬性

          documentPictureInPicture.window:返回當(dāng)前的畫中畫窗口,如果不存在則返回 null

          方法

          documentPictureInPicture.requestWindow(options):返回一個在畫中畫窗口打開時解析的 Promise 。如果在沒有用戶同意的情況下調(diào)用它, Promise 將被拒絕。options 包括兩個參數(shù):

          • width:設(shè)置畫中畫窗口的初始寬度。
          • height:設(shè)置畫中畫窗口的初始高度。

          事件

          documentPictureInPicture.onenterdocumentPictureInPicture 打開畫中畫窗口時觸發(fā)。

          例子

          手下我們通過下面的 HTML 設(shè)置自定義視頻播放器和按鈕元素以在畫中畫窗口中打開視頻播放器。

          <div id="playerContainer">
            <div id="player">
              <video id="video"></video>
            </div>
          </div>
          <button id="pipButton">打開畫中畫窗口!</button>

          打開畫中畫窗口

          當(dāng)用戶單擊按鈕打開空白的畫中畫窗口時,下面的 JavaScript 會調(diào)用documentPictureInPicture.requestWindow(),然后返回的 promise 使用一個畫中畫窗口 JavaScript 對象進(jìn)行解析。然后使用 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);
          });

          設(shè)置畫中畫窗口的大小

          我們可以通過 widthheight 屬性來設(shè)置畫中畫窗口的大小。(如果選項值太大或太小而無法適應(yīng)用戶友好的窗口大小,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);
          });

          將樣式表復(fù)制到畫中畫窗口

          要從原始窗口復(fù)制所有 CSS 樣式表,我們可以循環(huán)遍歷 styleSheets 文檔中顯式鏈接或嵌入的 CSS 樣式表,并將它們附加到畫中畫窗口。

          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);
          });

          畫中畫窗口關(guān)閉時的處理

          我們可以偵聽窗口的 "pagehide" 事件來了解畫中畫窗口的關(guān)閉時機(網(wǎng)站啟動它或用戶手動關(guān)閉它)。事件處理程序是將元素從畫中畫窗口中取出的好地方,如下所示。

          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() 方法可以直接關(guān)閉畫中畫窗口。

          // Close the Picture-in-Picture window programmatically. 
          // The "pagehide" event will fire normally.
          pipWindow.close();

          監(jiān)聽網(wǎng)站何時進(jìn)入畫中畫

          我們可以監(jiān)聽 documentPictureInPicture"enter" 事件來感知畫中畫窗口何時打開。這個事件包含一個用于訪問畫中畫窗口的 window 對象。

          documentPictureInPicture.addEventListener("enter", (event) => {
            const pipWindow = event.window;
          });

          訪問畫中畫窗口中的元素

          我們可以從 documentPictureInPicture. requestwindow() 返回的對象或使用 documentPictureInPicture 訪問畫中畫窗口中的元素:

          const pipWindow = documentPictureInPicture.window;
          if (pipWindow) {
            // Mute video playing in the Picture-in-Picture window.
            const pipVideo = pipWindow.document.querySelector("#video");
            pipVideo.muted = true;
          }

          檢查網(wǎng)站是否支持

          要檢查是否支持文檔畫中畫 API,可以使用:

          if ('documentPictureInPicture' in window) {
            // The Document Picture-in-Picture API is supported.
          }

          最后

          參考:

          • https://developer.chrome.com/docs/web-platform/document-picture-in-picture
          • https://developer.chrome.com/blog/watch-video-using-picture-in-picture/
          • https://developer.mozilla.org/docs/Web/API/Window/open
          • https://developer.mozilla.org/docs/Web/API/Element/append
          • https://lazy-guy.github.io/tomodoro/index.html

          往期回顧

          #

          如何使用 TypeScript 開發(fā) React 函數(shù)式組件?

          #

          11 個需要避免的 React 錯誤用法

          #

          6 個 Vue3 開發(fā)必備的 VSCode 插件

          #

          3 款非常實用的 Node.js 版本管理工具

          #

          6 個你必須明白 Vue3 的 ref 和 reactive 問題

          #

          6 個意想不到的 JavaScript 問題

          #

          試著換個角度理解低代碼平臺設(shè)計的本質(zhì)

          回復(fù)“加群”,一起學(xué)習(xí)進(jìn)步

          瀏覽 135
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  翔田千里无修正XXX | 免费直接观看黄色网页 | 丁香九月婷婷 | www.日本 爽久久.cou | 麻豆精品秘 国产AV |