iOS Safari全屏需同时满足:用户点击同步触发、video标签硬编码playsinline和webkit-playsinline、调用document.documentElement.requestFullscreen()、viewport-fit=cover等meta声明及CSS安全区适配。

requestFullscreen() 必须由用户点击触发,且不能加 delay
iOS Safari 对全屏调用极其严格:哪怕只是 setTimeout(() => el.requestFullscreen(), 0),也会被静默拒绝或抛出 TypeError: Document not active。它只认“真实、同步、无中间层”的用户手势。
- ✅ 正确写法:
button.addEventListener('click', () => videoEl.requestFullscreen()) - ❌ 错误写法:在
load、canplay、setTimeout或 Promise 回调里调用 - ⚠️ 注意:
videoEl必须已插入 DOM,且不能是隐藏状态(display: none或visibility: hidden)
video 标签必须同时带 playsinline 和 webkit-playsinline
缺一不可。iOS 不认 JS 动态设置,必须硬编码在 HTML 里;否则点全屏按钮可能黑屏、无响应,或直接跳转原生播放器(失去页面控制权)。
- ✅ 正确写法:
- ❌ 错误写法:
el.setAttribute('playsinline', 'true')(无效) - ⚠️ 注意:即使你不用内联播放,也**不能移除**这两个属性——移除后 iOS 反而更难进入/退出全屏,尤其在微信 WebView 中
全屏目标选 document.documentElement 还是 video 元素?
二者行为差异很大。iOS Safari **不支持对 video 元素单独 requestFullscreen()**(会失败或降级为原生全屏),所以推荐直接全屏整个页面。
- ✅ 推荐:
document.documentElement.requestFullscreen()—— 页面级全屏,可控、稳定 - ❌ 避免:
videoEl.requestFullscreen()—— 在 iOS 上大概率静默失败,或触发不可控的系统视频播放器 - ⚠️ 补充:若用
document.documentElement,需确保 CSS 适配安全区,例如:body { padding-bottom: env(safe-area-inset-bottom); }
别忘了 viewport-fit=cover 和 Web App Meta
没有这个,页面底部会被 iPhone 刘海/Home Indicator 切掉,看着像“没全屏”。这不是 JS 问题,是视口声明缺失。
立即学习“前端免费学习笔记(深入)”;
- ✅ 必加 meta:
- ✅ 可选增强(提升沉浸感):
- ⚠️ 注意:
viewport-fit=cover在部分老 iOS 版本(如 iOS 10)无效,但 iOS 11+ 是刚需










