element.requestfullscreen()必须在用户可信手势中调用且返回promise,需.catch()捕获错误;正确写法仅限click/keydown等事件回调,元素须挂载、有尺寸、非跨域iframe未声明allow="fullscreen"则失败。

element.requestFullscreen() 必须在用户点击等可信手势中调用,否则浏览器直接拒绝;它不返回布尔值,而是 Promise,必须用 .catch() 捕获失败,不能靠“没报错”就认为成功。
requestFullscreen() 调用失败的典型错误和修复方式
常见报错是 NotAllowedError: Fullscreen request was denied 或控制台静默无反应。根本原因几乎总是:调用时机不在用户手势上下文中。
- 错误写法:
setTimeout(() => el.requestFullscreen(), 100)、document.addEventListener('DOMContentLoaded', ...)、Promise.then(() => el.requestFullscreen()) - 正确写法:只在
click、keydown(且event.isTrusted === true)等事件回调里直接调用 - 元素本身也得“合格”:已挂载(
document.body.contains(el) === true)、有尺寸(不能display: none或width/height: 0)、不是跨域<iframe></iframe>内未声明allow="fullscreen"的内容
如何安全兼容 Chrome/Firefox/Safari 的 requestFullscreen 方法
现代浏览器基本支持标准 requestFullscreen(),但 Safari 15.4–16.3 及部分旧 WebView 仍需前缀。不能只检测存在性,得按优先级顺序尝试调用。
- 先检查
el.requestFullscreen是否可调用,能则直接用并加.catch() - 否则 fallback 到
el.webkitRequestFullscreen(Safari)、el.mozRequestFullScreen(旧 Firefox)、el.msRequestFullscreen(IE11,现已可忽略) - 不要写成
el.requestFullscreen || el.webkitRequestFullscreen—— 这种逻辑在 Safari 中会误选不可用的requestFullscreen方法 - 对
<video></video>等媒体元素,可直接调用;对普通<div>,建议设 <code>min-width: 300px; min-height: 200px,避免 Safari 静默拒监听全屏状态变化只能靠 document.fullscreenElement + fullscreenchange
别自己维护
isFullscreen = true/false,状态变更来源太多(ESC、标签页切换、双击、外部 API 调用),手动同步必不同步。- 监听必须绑定在
document上:document.addEventListener('fullscreenchange', handler),绑在元素上无效 - 判断依据唯一可靠:读
document.fullscreenElement—— 是null表示退出,否则就是当前被全屏的 DOM 元素(注意拼写是fullscreenElement,不是fullScreenElement) - 退出时不要在
fullscreenchange回调里再调document.exitFullscreen(),否则可能触发循环(比如用户点两次退出按钮) - 移动端(尤其 iOS Safari)不支持真正全屏,
document.fullscreenElement始终为null,此时只能靠 CSS(如height: 100dvh)模拟视觉全屏
:fullscreen 伪类样式为什么不起作用
:fullscreen不是全局开关,它只作用于当前被requestFullscreen()调用的那个元素本身,而且规则必须带明确选择器前缀。- 写法必须是
#player:fullscreen或video:fullscreen,不能只写:fullscreen或*:fullscreen - Safari 仍需
#player:-webkit-full-screen,Firefox 和 Chrome 支持标准:fullscreen,建议并列写多条 - 全屏后浏览器会重置部分默认样式(如
body的 margin、背景),所以常要显式写#player:fullscreen { margin: 0; width: 100vw; height: 100vh; } - 别依赖
body:fullscreen—— 真正被全屏的是你调用requestFullscreen()的那个元素,不是body
最容易被忽略的一点:全屏 API 的行为在 iframe 内受限极严,即使同源,也必须给
<iframe></iframe>加allow="fullscreen"属性,否则requestFullscreen()直接失败且不报错;而用户按 F11 进入的浏览器级全屏,document.fullscreenElement始终为null,网页完全感知不到。 - 监听必须绑定在











