全屏API调用失败主因是触发时机不当或权限不足:必须由用户手势直接触发,禁用异步调用;HTTPS环境必需;安卓WebView需降级webkitEnterFullscreen();沉浸式体验依赖viewport配置与PWA模式。

全屏 API 调用失败常见原因
调用 element.requestFullscreen() 报错 “Failed to execute 'requestFullscreen' on 'Element'” 多数不是代码写错了,而是触发时机或权限问题。浏览器强制要求全屏必须由用户手势(如 click、touchend)直接触发,不能在异步回调(如 setTimeout、fetch.then)里调用。
实操建议:
- 确保绑定在原生事件处理器中,例如:
button.addEventListener('click', () => video.requestFullscreen()) - 避免在 Vue 的
@click.native或 React 的合成事件里“间接”调用——先检查event.isTrusted === true - 部分安卓 WebView(如旧版微信内置浏览器)不支持
requestFullscreen(),需降级为webkitEnterFullscreen()(仅限<video></video>元素) - Chrome 92+ 对非 HTTPS 环境禁用全屏 API,本地
file://协议下必失败,务必用http-server或live-server启服务测试
沉浸式体验(display: fullscreen 和 navigation 元素)
所谓“沉浸”,其实是让页面内容撑满整个视口、隐藏地址栏/状态栏,但不走标准全屏 API。它依赖的是 viewport 配置和系统级元标签,和 requestFullscreen() 是两套机制。
关键配置项:
立即学习“前端免费学习笔记(深入)”;
- 必须加
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">,其中viewport-fit=cover是 iOS 安全区域适配前提 - iOS Safari 下隐藏地址栏:滚动后自动收起,但首次加载时仍可见;可通过
window.scrollTo(0, 1)强制触发(注意仅限非 body 滚动容器内有效) - Android Chrome 支持
<meta name="mobile-web-app-capable" content="yes">+ 添加到主屏幕后启动为 PWA 模式,此时可接近真正沉浸(无 URL 栏、状态栏半透明) -
display: fullscreen不是 CSS 属性,是 Web App Manifest 中的display字段值,仅对 PWA 有效,且需配合start_url和scope
如何判断当前是否处于全屏或沉浸状态
不能只靠 document.fullscreenElement,因为沉浸模式下它始终为 null。需要组合检测多个信号。
推荐判断逻辑:
- 检测全屏:用
document.fullscreenElement !== null或监听fullscreenchange事件 - 检测“类沉浸”(PWA 全屏模式):检查
matchMedia('(display-mode: standalone)').matches或matchMedia('(display-mode: fullscreen)').matches - 运行时估算:对比
window.innerHeight和screen.height,若差值 > 50px(比如 Android 地址栏高度),大概率未沉浸;iOS 上更可靠的方式是读取safeAreaInsets(通过env(safe-area-inset-top)CSS 变量或 JS 注入) - 注意:Safari 在“添加到主屏幕”后启动,
navigator.standalone为true,但该属性已被废弃,仅作兼容参考
兼容性兜底与渐进增强策略
没有一套代码能同时满足所有设备的“全屏+沉浸”。必须分层处理:优先保核心功能,再叠加体验增强。
最小可行路径:
- 基础层:所有设备都支持
height: 100vh+overflow: hidden,模拟视觉全屏(注意vh在 iOS Safari 滚动时会动态变化,可用dvh替代) - 增强层:检测
'onfullscreenchange' in document决定是否挂载全屏按钮;检测'standalone' in navigator或 manifest display 值决定是否提示“添加到主屏幕” - 兜底层:微信内嵌浏览器完全屏蔽全屏 API,但允许
<video></video>调用webkitEnterFullscreen();QQ 浏览器支持requestFullscreen()但需加前缀webkitRequestFullscreen() - 别忽略 orientation:横屏全屏体验更稳定,可在进入前用
screen.orientation.lock('landscape')尝试锁定(需用户手势触发,且仅部分浏览器支持)
真正难的不是调用某个 API,而是识别当前运行环境到底给了你什么能力——每次更新 iOS 或 Chrome 版本,fullscreenchange 触发时机、safe-area-inset 行为、甚至 PWA 安装提示逻辑都可能微调。留好日志钩子,比写死判断更可靠。



















