浏览器原生的 画中画 特性

news2024/12/23 16:16:57

Chrome 116 作为Google浏览器的最新稳定版本已正式发布。Chrome 浏览器支持视频画中画(HTMLVideoElement)已有一段时间,而 Chrome 116 则新增了文档画中画模式。这种"文档画中画"模式提供了一个始终在顶部的窗口,可以填充任意 HTML 元素。因此,它可以为视频内容提供更丰富的体验,也可用于其他目的。

例如,它可用于在显示视频画中画内容的同时显示文本或聊天信息和其他内容,也可用于显示广告。

Chrome 116 还增加了显示和内容可见性动画、对 Fetch API 的 BYOB 支持、CSS 运动路径以及其他各种开发人员新增功能。

Chrome 浏览器发布博客还介绍了 Chrome 116 中的许多安全修复。

同时,Chrome 浏览器 117 正在添加 CSS 叠加属性、不安全下载警告、添加 CSS 网格布局模块二级(subgrid)以及大量其他开发人员添加的内容,这些内容将在 9 月份以稳定版的形式发布。

Web API 接口参考 | MDN

比较值得关注的新增功能就是网页的画中画 API 了(Document Picture in Picture API )。

 

 

简介

画中画 API 可以打开一个始终位于当前网页顶部的窗口,这个窗口可以填充任意的 HTML 内容。它扩展了现有的 Picture-in-Picture API for <video> (其只允许将 <video> 元素放入画中画窗口中)。

图片

通过 Document Picture-in-Picture API 创建的 Picture-in-Picture 窗口其实很类似于通过 window.open() 打开的空白的同源窗口,但也存在一些差异:

  • 画中画窗口永远会浮动在其他窗口之上。

  • 当前窗口关闭后会立即关闭打开的画中画窗口

  • 无法通过地址导航到画中画窗口。

  • 画中画窗口的位置无法由网站设置。

使用场景

这个 API 还是有挺多实用场景的,首先我们还是可以用它来实现自定义视频播放器,虽然现有的 Picture-in-Picture API for <video> 也可以实现,但是效果非常有限(参数少,样式设置灵活)。现在通过新的画中画 API,网站可以提供一些自定义组件和参数(例如字幕、播放列表、时间控制、喜欢和不喜欢的视频),来改善用户的画中画视频体验。另外我们还可以用它来实现一个体验非常好的网页视频会议功能等等。

用法

属性

documentPictureInPicture.window:返回当前的画中画窗口,如果不存在则返回 null

方法

documentPictureInPicture.requestWindow(options):返回一个在画中画窗口打开时解析的 Promise 。如果在没有用户同意的情况下调用它, Promise 将被拒绝。options 包括两个参数:

  • width:设置画中画窗口的初始宽度。

  • height:设置画中画窗口的初始高度。

事件

documentPictureInPicture.onenterdocumentPictureInPicture 打开画中画窗口时触发。

例子

手下我们通过下面的 HTML 设置自定义视频播放器和按钮元素以在画中画窗口中打开视频播放器。

<div id="playerContainer">
  <div id="player">
    <video id="video"></video>
  </div>
</div>
<button id="pipButton">打开画中画窗口!</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 属性来设置画中画窗口的大小。(如果选项值太大或太小而无法适应用户友好的窗口大小,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);
});

将样式表复制到画中画窗口

要从原始窗口复制所有 CSS 样式表,我们可以循环遍历 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);
});

画中画窗口关闭时的处理

我们可以侦听窗口的 "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();

监听网站何时进入画中画

我们可以监听 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;
}

检查网站是否支持

要检查是否支持文档画中画 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/913692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sql server 、mysql CTE 公用表表达式

sql server 详细 mysql CTE CTE 是一个命名的临时结果集&#xff0c;作用范围是当前语句。CTE可以理解成一个可以复用的子查询&#xff0c;当然跟子查询还是有点区别的&#xff0c;CTE可以引用其他CTE&#xff0c;但子查询不能引用其它子查询。所以&#xff0c;开发中建议…

新高-新低指数(NH-NL)指标公式,判断多空力度

在《以交易为生》这本书中&#xff0c;作者埃尔德根据其经验&#xff0c;认为新高-新低指数(NH-NL)是股市的最佳领先指标。在任意一天中&#xff0c;创一年新高的股票是强势股&#xff0c;而创一年新低的股票是弱势股。新高-新低指数通过比较强势股和弱势股的数量来跟踪市场领导…

【Jenkins】持续集成部署学习

【Jenkins】持续集成部署学习 【一】安装部署【1】Jenkins所处位置【2】Docker安装Gitlab&#xff08;1&#xff09;首先准备一台空的虚拟机服务器&#xff08;2&#xff09;安装服务器所需的依赖&#xff08;3&#xff09;Docker的安装&#xff08;4&#xff09;阿里云镜像加速…

「UG/NX」Block UI 截面构建器SectionBuilder

✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#

容器插件工具kubectl-images

容器插件工具 简单方便查找镜像源信息&#xff0c;kubectl-images 代码地址&#xff1a;https://github.com/chenjiandongx/kubectl-images 此工具可以快捷执行命令来查看集群内ns&#xff0c;pod&#xff0c;及镜像等信息&#xff1b; 查看帮助项 ~ kubectl images --help …

HarmonyOS开发第一步,熟知开发工具DevEco Studio

俗话说的好&#xff0c;工欲善其事&#xff0c;必先利其器&#xff0c;走进HarmonyOS第一步&#xff0c;开发工具必须先行&#xff0c;当然了&#xff0c;关于开发工具的使用&#xff0c;官网和其他的博客也有很多的讲解&#xff0c;但是并没有按照常用的功能进行概述&#xff…

ELK中Logstash的基本配置和用法

文章目录 Logstash的条件判断Logstash的输入插件Stdin输入文件内容输入filter过滤器 Logstash的输出插件测试收集日志启动kibana在kibana中配置索引数据 在 《Elasticsearch搜索引擎系统入门》中简单描述了Logstah的安装&#xff0c;本篇文章将较为详细的讲解Logstash的基本配置…

Docker搭建个人网盘、私有仓库

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘 [rootlocalhost ~]# docker pull mysql:5.6 [rootlocalhost ~]# docker pull owncloud [rootlocalhost ~]# docker run -itd --name mysql --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 [rootlocalhost ~]# doc…

汽车企业数据泄露频发,其中特斯拉数据泄露影响达7.5万人

据美国有线电视新闻网&#xff08;CNN Business&#xff09;8月19日报道&#xff0c;特斯拉此前发生的大规模数据泄露事件&#xff0c;泄露了超过7.5万人的个人信息&#xff0c;这是“内部不法行为”的结果。 特斯拉在发给员工的通知中表示&#xff0c;被泄露的“特斯拉文件”包…

CMS数据库搭建

前置条件&#xff1a;在虚拟机中安装phpstudy。 1.将cms的压缩包通过远程桌面放到虚拟机&#xff0c;将压缩包解压&#xff0c;将解压后的cms文件夹放到phpstudy安装目录下的www文件夹中&#xff0c;路径如下&#xff08;安装时的路径可能不同&#xff09;&#xff1a; C:\ph…

易基因:MeRIP-seq等揭示ALKBH5介导m6A去甲基化调控皮肤创面再上皮化分子机制|科研进展

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 哺乳动物的损伤皮肤屏障完整性恢复通过创面愈合基本机制实现&#xff0c;这是一个包括凝血、炎症、再上皮化&#xff08;re-epithelialization&#xff09;、肉芽组织形成和疤痕重塑的多…

MSTP多生成树协议(第二课)

MSTP负载均衡 实验 需求 1&#xff09;PC1属于 vlan 10 &#xff0c;IP地址为 192.168.10.1/24&#xff0c; 网关为 192.168.10.2542&#xff09;PC2属于 vlan 20 &#xff0c;IP地址为 192.168.20.1/24&#xff0c; 网关为 192.168.20.254**3&#xff09;确保PC1与PC2互通4…

pytorch中的register_buffer

今天在一个模型的init中遇到了self.register_buffer(‘running_mean’, torch.zeros(num_features)) register_buffer(self, name, tensor)是一个PyTorch中的方法&#xff0c;它的作用是向模块&#xff08;module&#xff09;中添加一个持久的缓冲区&#xff08;buffer&#xf…

【优选算法】—— 字符串匹配算法

在本期的字符串匹配算法中&#xff0c;我将给大家带来常见的两种经典的示例&#xff1a; 1、暴力匹配&#xff08;BF&#xff09;算法 2、KMP算法 目录 &#xff08;一&#xff09;暴力匹配&#xff08;BF&#xff09;算法 1、思想 2、演示 3、代码展示 &#xff08;二&…

nginx基于端口如何配置虚拟主机

在 Nginx 中配置基于端口的虚拟主机&#xff08;也称为服务器块&#xff09;与配置基于域名的虚拟主机类似&#xff0c;但是你需要指定监听的端口。以下是基于端口的虚拟主机配置示例&#xff1a; 假设我们要配置两个不同的虚拟主机&#xff0c;一个监听 8080 端口&#xff0c…

【自制C/C++小项目JuLongEditor】使用Windows控制台API来制作一个简单的文本编辑器

2023年8月22日&#xff0c;周二下午 昨天花了一个下午和晚上来制作的&#xff0c; 实现了一些基本的功能&#xff0c; 但由于代码只有130行&#xff0c;所以存在很多不足之处 GitHub&#xff1a;GitHub - JuLongZhiLu/JuLongEditor: C/C小项目&#xff0c;使用Windows控制台…

Hlang-从零开始编写一个vscode代码提示插件

文章目录 前言Hlang适配实现语法提示package.json配置编写提示语法配置语法高亮执行打包前言 通过一段时间的努力,Hlang是开发完毕了,但是我们还需要为它提供一个IDE。那么从零开发显然是不可取的,这会大大加大开发难度。但是我们可以基于vscode这个神奇的物质。所以我们只…

STM32驱动MAX30102心率血氧传感器(OLED显示)

STM32驱动MAX30102心率血氧传感器&#xff08;OLED显示&#xff09; 简介电气参数系统框图接线代码结果总结 简介 MAX30102是一个集成的脉搏血氧仪和心率监测仪模块。它包括内部led&#xff0c;光电探测器&#xff0c;光学元件&#xff0c;和低噪声电子与环境光排斥。MAX30102…

《三国》时期,谁才是优秀的项目经理

大家好&#xff0c;我是老原。 上一次细读三国&#xff0c;还是在老原高中的时候&#xff0c;当时只觉得他们神仙打架&#xff0c;谋略过人。 现在毕业也快10年&#xff0c;重读三国&#xff0c;我又有了新的一些发现——关于管理者。 金无赤足&#xff0c;人无完人。《三国…

stm32片内读写项目总结(多字节读写tongxindu)

1.flash操作驱动程序 a头文件 #ifndef FLASH_H #define FLASH_H #include “stm32f4xx.h” #define BOARD_NUM_ADDR 0x0800C000 #define STM32_FLASH_BASE 0x08000000 //STM32 FLASH的起始地址 #define FLASH_WAITETIME 50000 //FLASH等待超时时间 //FLASH 扇区的起始地址…