全屏需用户原生点击触发且严格遵循平台限制:iOS仅视频支持真正全屏,Android依赖PWA;须用100dvh、orientation.lock、viewport适配及manifest配置,并监听fullscreenchange统一管理样式与退出。

不能只调用 requestFullscreen() 就算完事——它只是把元素放大到屏幕尺寸,不隐藏地址栏、不锁方向、不处理键盘弹出退出,演示时一碰就破。
全屏必须由用户点击触发,且不能跨事件上下文
常见错误是把全屏逻辑封装成独立函数,然后在 fetch.then、setTimeout 或 Vue 的 @click 合成事件里调用。浏览器会静默拒绝,控制台可能只报 TypeError: Document not active 或根本无提示。
- 必须绑定在原生事件处理器中:
button.addEventListener('click', () => el.requestFullscreen()) - 若用框架(如 React/Vue),检查
event.isTrusted === true,避免被合成事件“污染” - iframe 内调用需父页加
<iframe src="..." allow="fullscreen">,否则直接失败
移动端真正沉浸要靠 viewport + display-mode + playsinline 组合
iOS Safari 对 requestFullscreen() 极其保守:非 <video> 元素基本无效;即使成功,地址栏仍残留;横竖屏切换还会自动退出。Android Chrome 则依赖 PWA 模式才能隐藏状态栏。
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">是 iOS 安全区适配前提 - 必须提供有效的
manifest.json,含"display": "standalone"或"fullscreen",并用<link rel="manifest" href="/manifest.json">引入 - 若演示含视频,
<video playsinline>不可少,否则 iOS 会跳转原生播放器,失去 JS 控制权
进全屏后立刻锁定视口和方向,否则布局错乱
全屏后 100vh 会失效(滚动条、地址栏收缩导致高度突变),screen.orientation.lock('landscape') 能防 Safari 地址栏意外浮现,但仅 Android 和部分桌面 Chrome 支持。
立即学习“前端免费学习笔记(深入)”;
- 用
100dvh替代100vh,它是动态视口单位,响应地址栏收起/展开 - 监听
fullscreenchange事件,在进入后立即执行:document.body.style.height = '100dvh'; screen.orientation.lock('landscape').catch(() => {}); - 键盘弹出会强制退出全屏(尤其 Android),无法拦截,只能在
fullscreenchange中检测并提示用户收起键盘
退出全屏必须用 document.exitFullscreen(),且要 try/catch
很多人误写成 el.exitFullscreen() 或漏掉错误捕获,导致后续 JS 中断。更隐蔽的问题是:退出后未重置 overflow、position 等样式,页面滚动异常或内容被截断。
- 统一使用
document.exitFullscreen(),它不接受参数,也不返回 Promise - 务必包裹
try { await document.exitFullscreen(); } catch (e) { /* 忽略或记录 */ },因为退出可能因非全屏状态而抛错 - 监听
fullscreenchange,在document.fullscreenElement === null时恢复 body 样式:document.body.style.height = '';
最易被忽略的是:iOS Safari 基本不支持非视频元素的真正沉浸式全屏,哪怕所有配置都对,它也只做缩放。别花时间调试“为什么地址栏还在”,直接降级为 position: fixed; inset: 0; 模拟视觉全屏,并告知用户这是平台限制。


















