requestfullscreen() 必须由用户可信手势(如click、touchend)直接触发,否则被浏览器安全策略拒绝;需显式检测各浏览器前缀api、用document.fullscreenelement判断状态、document.exitfullscreen()退出并捕获promise错误。

requestFullscreen() 必须由用户点击或触摸等可信手势直接触发,否则浏览器会静默拒绝或抛出 NotAllowedError。这不是兼容性问题,而是现代浏览器的强制安全策略。
为什么点按钮没反应或报“API can only be initiated by a user gesture”
错误通常出现在这几种情况:
- 把
el.requestFullscreen()放在setTimeout、Promise.then或页面加载完成回调里——哪怕只延迟 0 毫秒,也会被判定为“非用户发起” - 绑定的是
mouseenter或focus这类非交互事件,而不是click、touchend或keydown(且需event.isTrusted === true) - 目标元素还没挂载到 DOM 中,比如
document.createElement('div')后立刻调用,但没执行document.body.appendChild(el) - 对 iframe 内部元素调用,而该 iframe 缺少
allow="fullscreen"属性(跨域时尤其关键)
如何正确调用 requestFullscreen 并兼容老浏览器
不要用 || 链式 fallback,因为部分旧 Safari 会同时暴露 requestFullscreen(不可用)和 webkitRequestFullscreen(可用),必须显式判断:
function enterFullscreen(el) {
if (el.requestFullscreen) {
return el.requestFullscreen();
}
if (el.webkitRequestFullscreen) {
return el.webkitRequestFullscreen();
}
if (el.mozRequestFullScreen) {
return el.mozRequestFullScreen(); // 注意:Full 是小写
}
if (el.msRequestFullscreen) {
return el.msRequestFullscreen(); // IE11,已基本可忽略
}
throw new Error('Fullscreen API not supported');
}
// 使用示例
document.getElementById('myVideo').addEventListener('click', () => {
enterFullscreen(document.getElementById('myVideo'))
.catch(err => console.warn('全屏失败:', err.name));
});
注意:requestFullscreen() 返回 Promise,务必用 .catch() 捕获拒绝,不要只依赖 fullscreenerror 事件——它触发不稳定,且错误信息模糊。
进入后怎么确认真全屏了,以及退出逻辑怎么写
不能靠变量记录状态,唯一可靠依据是 document.fullscreenElement:
- 值为
null→ 未全屏(包括刚退出、从未进入、或 F11 浏览器级全屏时) - 值为某个 DOM 元素 → 该元素正在全屏;可用来动态加 class、重设尺寸或暂停其他动画
- 监听必须写在
document上:document.addEventListener('fullscreenchange', handler),绑在元素上无效
退出统一用 document.exitFullscreen(),它也返回 Promise:
document.exitFullscreen().catch(e => {
// e.name 可能是 'NotFoundError'(本来就没全屏)或 'NotAllowedError'
if (e.name !== 'NotFoundError') {
console.error('退出异常:', e);
}
});
别在 fullscreenchange 回调里自动调用 exitFullscreen(),双击按钮或快速切换容易引发竞态。
:fullscreen 伪类和移动端适配的关键细节
CSS 的 :fullscreen 只对通过 API 进入全屏的元素生效,F11 触发的浏览器全屏不触发它。常见坑点:
- 旧版 Safari 要用
::-webkit-full-screen,但现代版本已支持标准:fullscreen,建议优先写标准写法,再加前缀兜底 - 移动端 iOS Safari 对普通
<div> 全屏限制极严,即使用户点击也可能被拦截;<code><video></video>相对宽松,但需确保没设playsinline - 全屏后视口单位推荐用
dvh(dynamic viewport height)替代vh,避免 Safari 地址栏收起/展开导致高度跳变 - 全屏状态下,
document.scrollingElement可能失效,滚动监听要改用window或目标元素自身
真正难处理的不是调用本身,而是全屏后焦点管理、键盘事件(如 Esc、F11)、iframe 嵌套层级、Web Components Shadow DOM 中 fullscreenElement 的归属判断——这些在复杂 UI 中往往比“进不去全屏”更耗调试时间。











