在前端开发中,我们经常会遇到这样的需求:弹出一个浮动窗口来显示一些实时信息、工具栏或视频内容。过去我们会用 window.open(),后来越来越多的开发者倾向于使用 Modal。但现在,一个更现代的 API 出现了——Document Picture-in-Picture API,它能带来一种完全不同的浮窗体验。

为什么我们需要新的解决方案?

传统的 window.open() 虽然简单易用,但限制非常多:

  • ❌ 容易被浏览器拦截(尤其是在移动端)

  • ❌ 用户体验差(新窗口可能被挡住)

  • ❌ 样式控制受限(几乎无法用 CSS 美化)

  • ❌ 无法保证窗口始终置顶

Modal(模态框)虽然解决了很多问题,但它始终依附于当前页面 DOM,一旦用户切换了标签页、最小化了窗口,就无法再查看。

Document Picture-in-Picture API 是什么?

这是浏览器提供的原生 API,它允许你创建一个独立的、始终置顶的小窗口,并加载自定义 HTML 内容。它和视频画中画(Video PiP)类似,但不是只能放视频,而是可以放任何 HTML 页面内容

✅ 从技术上说,它本质上是一个轻量、独立的浏览器子窗口,但有专门的样式控制权。

🆚 Modal 和 Document PiP 的对比分析

对比维度

Modal(模态框)

Document PiP(文档浮窗)

是否属于当前页面

✅ 是

❌ 否,独立页面

是否总在顶层显示

❌ 需控制 z-index

✅ 浏览器层面置顶

是否能脱离标签页

❌ 否

✅ 是,切标签页依然保留显示

样式与内容控制

✅ 可通过 React/Vue 完整控制

✅ 需通过 HTML 字符串或 JS 注入

是否能被拦截

✅ 不会

✅ 不会

用户体验

✅ 优秀

✅ 更适合小工具类浮窗

使用场景

表单、对话框、确认弹窗等

数据面板、悬浮工具栏、直播小窗等

🛠 快速上手指南

检查浏览器是否支持

由于这个现代API的兼容性并没有那么完美

图片

在代码中需要检查浏览器是否支持

const isSupported = "documentPictureInPicture"inwindow;

创建一个浮窗

asyncfunctionopenPipWindow() {if (!("documentPictureInPicture"inwindow)) return;const pipWindow = await documentPictureInPicture.requestWindow({width: 400,height: 300});// 设置窗口内容(你可以用框架进一步封装)pipWindow.document.body.innerHTML = \`<div style="padding: 20px; background: #f0f0f0;"><h2>🎉 自定义浮窗</h2><p>这是对 window.open 的完美替代</p></div>\`;
}

📌 注意: 当前只能通过字符串方式注入内容,暂不支持直接挂载 Vue/React 组件,但可以用 iframe 或构建工具封装。

视频弹窗?请用 Video PiP!

<videoid="myVideo"controls><sourcesrc="video.mp4"type="video/mp4">
</video>
<buttononclick="togglePiP()">📺 画中画</button><script>
asyncfunctiontogglePiP() {const video = document.getElementById('myVideo');if (!document.pictureInPictureElement) {await video.requestPictureInPicture(); // 开启画中画} else {awaitdocument.exitPictureInPicture(); // 退出}
}
</script>

📊 典型场景推荐

实时仪表盘

显示用户活跃、订单数量、监控指标等 —— 适合后台管理端、BI 系统等。

const pipWindow = await documentPictureInPicture.requestWindow();
pipWindow.document.body.innerHTML = `<div style="background: #1a1a1a; color: white; padding: 20px;"><h3>📈 实时指标</h3><div>当前在线:245</div><div>异常警告:2</div></div>
`;

套电落地页聊天窗

用于落地页收集线索、在线客服、AI 助手浮窗,让用户切换页面时仍能继续对话。

const chatWindow = await documentPictureInPicture.requestWindow();
chatWindow.document.body.innerHTML = `<div style="padding: 10px; font-family: sans-serif;"><h4>🧑‍💼 在线客服</h4><div style="height: 200px; overflow-y: auto; border: 1px solid #ccc;">欢迎咨询,我们在线!</div><input type="text" placeholder="输入您的问题..." style="width: 100%; margin-top: 10px;"></div>
`;

实用技巧 & 最佳实践

🚨 错误处理

try {const pipWindow = await documentPictureInPicture.requestWindow();
} catch (error) {if (error.name === 'NotAllowedError') {console.log('用户拒绝了浮窗权限');}
}

📐 响应式尺寸建议

const pipWindow = await documentPictureInPicture.requestWindow({width: Math.min(400, window.innerWidth * 0.8),height: Math.min(300, window.innerHeight * 0.8)
});

不知道你是否有这样的疑问:

❓为什么不直接用 Modal?还能用 JSX 或组件,性能也更好?

这是一个非常好的问题。确实,在页面内部使用 Modal 组件(例如 antd、Element Plus 等)更适合处理输入、表单、提示等页面交互内容,代码复用度也高。但:

  • Modal 只能在当前页面中显示,标签页切换或窗口最小化后就不可见;

  • Document PiP 则是 浏览器级别的浮窗,可以独立存在、随时可见,特别适合那些希望“常驻桌面”的场景。

所以,选择哪个更好?

  • 👨‍💻 推荐使用 Modal: 表单交互、流程控制、确认提示等。

  • 🖥️ 推荐使用 Document PiP: 实时数据窗口、悬浮工具、小地图、直播窗等。

总结

为不同场景选择最合适的浮窗方案

场景

推荐方案

表单输入

✅ Modal

实时监控窗口

✅ Document PiP

简单的确认提示

✅ Modal

常驻小工具栏

✅ Document PiP

视频画中画

✅ Video PiP API

📢建议

如果你想实现:

  • 不被弹窗拦截器阻止的浮窗功能;

  • 永远置顶、跨标签页的小窗口;

  • 快速集成、无需第三方组件的解决方案;

👉 那就大胆尝试 Document Picture-in-Picture API 吧!它或许会成为你项目中意想不到的提升利器!

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【指南版】网络与信息安全岗位系列(三):安全运维工程师

一、安全运维工程师到底做什么&#xff1f;—— 用校园场景帮你理解简单说&#xff0c;安全运维工程师就像 “网络世界的安保队长 系统管家”&#xff1a;既要实时监控网络和系统的 “异常动静”&#xff08;类似学校保安巡逻查隐患&#xff09;&#xff0c;又要负责日常的安全…

matlab——simulink学习(5向NXP库中添加新模块)

向NXP库中添加新的函数模块一、环境二、库添加模块1.打开文件夹2.创建文件3.添加S-Function三、浏览器添加模块一、环境 Windows10、MATLAB R2022b、安装NXP的S32K1XX系列工具包 二、库添加模块 1.打开文件夹 在文件系统中找到安装工具包的位置&#xff0c;用文件资源管理器…

使用ProxySql实现MySQL的读写分离

ProxySQL简介1、ProxySQL是一款开源的使用C编写的MySQL集群代理中间件&#xff1b;2、用于在MySQL数据库和客户端之间进行负载均衡、查询缓存、故障转移和查询分发&#xff1b;3、它可以作为中间层插入到应用程序和数据库之间&#xff1b;4、特点是高效灵活&#xff0c;使用简单…

WiFi 核心概念与实战用例全解

&#x1f4d6; 推荐阅读&#xff1a;《Yocto项目实战教程:高效定制嵌入式Linux系统》 &#x1f3a5; 更多学习视频请关注 B 站&#xff1a;嵌入式Jerry 1. WiFi基础与协议 WiFi&#xff08;Wireless Fidelity&#xff09;是基于IEEE 802.11协议族的无线局域网&#xff08;WLAN…

面向远程智能终端的超低延迟RTSP|RTMP视频SDK架构与实践指南

引言&#xff1a;遥操作时代&#xff0c;视觉链路已成“主控神经元” 从工业巡检到应急救援&#xff0c;从城市安防到边境监控&#xff0c;远程操控正成为智能终端与人机协同的重要落点。而在这些场景中&#xff0c;“视觉”不再只是用来观看的工具&#xff0c;而是贯穿感知、…

C++中的继承:从基础到复杂

目录 前言 1. 继承的基本概念 2. 继承方式与访问控制 3. 派生类与基类的对象转换 4. 继承中的作用域 5. 派生类的默认成员函数 6. 继承中的特殊关系 6.1 继承与友元 6.2 继承与静态成员 7. 复杂的菱形继承问题 8. 继承与组合的选择 9. 常见面试题 总结 前言 继承…

Eyevinn 彻底改变开源部署模式

该咨询公司借助Akamai云平台&#xff0c;为其创新的开源平台和可持续收益分成模式提供强大支持。 "时间就是金钱&#xff0c;我们通过Akamai云平台快速将开源云平台投入生产。" ——Eyevinn Technology研发副总裁 Jonas Birm实现可持续视频流媒体服务 自2013年以来&…

17day-人工智能-机器学习-分类算法-KNN

1. 什么是knn算法knn算法全名叫做k-近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09;&#xff0c;看到名字是不是能想到是算距离的&#xff0c;第一个k是指超参数的意思&#xff0c;就是可以认为设置的意思&#xff0c;这里是指最近的k个样本。2. 为什…

12-netty基础-手写rpc-编解码-04

netty系列文章&#xff1a; 01-netty基础-socket02-netty基础-java四种IO模型03-netty基础-多路复用select、poll、epoll04-netty基础-Reactor三种模型05-netty基础-ByteBuf数据结构06-netty基础-编码解码07-netty基础-自定义编解码器08-netty基础-自定义序列化和反序列化09-n…

解决 Windows 下的“幽灵文件”——记一次与带空格的 .gitignore 文件的艰难斗争

引言 你是否遇到过这样的情况&#xff1a;一个文件明明躺在你的文件夹里&#xff0c;ls 或 dir 命令都能清楚地看到它&#xff0c;但无论你用什么方法尝试删除&#xff0c;系统都冷酷地告诉你“找不到文件”&#xff1f; 就在今天&#xff0c;我就遇到了这样一个“幽灵”般的 .…

(易视宝)易视TV is-E4-G-全志A20芯片-安卓4-烧写卡刷工具及教程

&#xff08;易视宝&#xff09;易视TV is-E4-G-全志A20芯片-安卓4-烧写卡刷工具及教程PhoenixCard_V309烧录步骤&#xff1a;1、将TF或SD卡插入计算机&#xff0c;打开软件&#xff1b;2、选择固件所在目录&#xff1b;3、烧写模式选“卡量产”4、点击“烧录”开始量产&#x…

(数据结构)顺序表实现-增删查改

1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时…

【面试八股总结】线程/进程同步问题

一、同步与互斥 在线程并发执行的过程中&#xff0c;进程/线程之间存在协作的关系&#xff0c;例如有互斥、同步的关系。为了实现进程/线程间正确的协作&#xff0c;操作系统必须提供实现进程协作的措施和方法&#xff0c;主要的方法有两种&#xff1a; 锁&#xff1a;加锁、解…

大语言模型提示工程与应用:提示工程入门指南

提示工程入门 学习目标 在本课程中&#xff0c;我们将学习提示工程。 相关知识点 提示工程 学习内容 1 提示工程 提示工程是一门新兴学科&#xff0c;专注于设计和优化提示词以高效利用语言模型完成多样化任务。掌握提示工程能帮助开发者更深入理解大语言模型(LLM)的能力…

PostgreSQL 多级依赖血缘系统的设计与落地

一、业务背景&#xff1a;三类指标与四种状态指标类型定义规则依赖关系原子指标单表聚合&#xff08;SELECT WHERE GROUP&#xff09;无派生指标在原子/派生指标上加 WHERE、改 GROUP依赖 1~N 个父指标复合指标多个原子/派生指标做加减运算依赖 1~N 个父指标状态说明已保存草…

阿里云百炼平台创建智能体-上传文档

整体思路是&#xff1a; 1创建ram用户&#xff0c;授权 2上传文件获取FileSession 3调用智能体对话&#xff0c;传入FileSession 接下来每个步骤的细节&#xff1a; 1官方不推荐使用超级管理员用户获得accessKeyId和accessKeySecret&#xff0c;所以登录超级管理员账号创建…

剪映里面导入多张照片,p图后如何再导出多张照片?

剪映普通版本暂时没发现可以批量导出图片。这里采用其他方式实现。先整体导出视频。这里前期要注意设置帧率&#xff0c;一张图片的时长。 参考一下设置&#xff0c;帧率设置为30&#xff0c;图片导入时长设置为1s&#xff0c;这样的话&#xff0c;方便后期把视频切割为单帧。导…

怎么查看Linux I2C总线挂载了那些设备?

1. 根据系统启动查看设备树节点文件&#xff08;系统运行后的&#xff09; 比如&#xff1a;要查看I2C2i2c2: i2cfeaa0000 {compatible "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";reg <0x0 0xfeaa0000 0x0 0x1000>;clocks <&cru CLK_…

bat脚本实现获取非微软官方服务列表

Get-CimInstance -ClassName Win32_Service |Where-Object { $_.State -eq Running -and $_.StartMode -ne Disabled } | ForEach-Object {$isMicrosoft $false$signerInfo 无可执行路径if ($_.PathName) {# 提取可执行文件路径&#xff08;处理带引号/参数的路径&#xff09…

小程序难调的组件

背景。做小程序用到了自定义表单。前后端都是分开写的&#xff0c;没有使用web-view。所以要做到功能对称时间选择器。需要区分datetime, year, day等类型使用uview组件较方便 <template><view class"u-date-picker" v-if"visible"><view c…