video元素无法监听fullscreenchange事件,因该事件仅在document上触发且不冒泡;应使用document.addEventListener('fullscreenchange', handler),并通过setTimeout或Promise.resolve().then延迟读取document.fullscreenElement以确保状态准确。

为什么给 video 绑 fullscreenchange 没反应
因为这个事件根本不在元素上触发,只在 document 上。你写 videoEl.addEventListener('fullscreenchange', ...),回调永远不会执行——它不冒泡,也不支持绑定到任意节点。
正确做法是统一监听 document:
- 必须用
document.addEventListener('fullscreenchange', handler) - 不能用
window或videoEl或document.body - 事件名严格小写:
fullscreenchange,不是fullScreenChange或fullscreenchanged
document.fullscreenElement 读出来总是 null?
常见于 Safari(尤其 iOS)和刚进回调时。浏览器内部状态更新有微小延迟,直接读可能拿到旧值。
稳妥写法是加一层异步:
立即学习“前端免费学习笔记(深入)”;
- 用
setTimeout(() => { /* 读 document.fullscreenElement */ }, 0) - 或
Promise.resolve().then(() => { /* 同上 */ }) - 不要依赖
event.target或e.type判断方向,它们无法区分“进入”还是“退出”
按钮图标/文字没跟着 Esc 退出同步更新
用户按 Esc 退出全屏,但你的按钮还显示“退出全屏”,说明状态没及时刷新。这不是 UI 逻辑问题,而是事件监听没覆盖所有路径。
确保你监听的是真实切换完成后的状态:
- 只靠点击按钮存状态不够,必须响应
fullscreenchange实时更新 UI - 检查是否误调了
event.preventDefault()在keydown里拦截了 Esc - 避免在 handler 里立即调
document.exitFullscreen(),容易引发状态错乱 - 按钮文案建议用布尔判断:
document.fullscreenElement ? '退出全屏' : '全屏'
localStorage 记住偏好但页面一加载就自动全屏?
这是典型的手势触发违规。浏览器明确要求 requestFullscreen() 必须由用户操作(如 click、touchend)发起,不能在 DOMContentLoaded 或 load 里直接调用。
正确做法是分离“状态记忆”和“动作触发”:
- 加载时读
localStorage.getItem('mediaPlayerFullscreen'),仅用于设置按钮样式或提示文案 - 全屏动作仍绑定在用户点击上,点击时再调
videoEl.requestFullscreen() - 退出全屏同理:监听
fullscreenchange,检测到!document.fullscreenElement就存'false'
最易被忽略的点:iOS Safari 中 fullscreenchange 回调刚执行时 document.fullscreenElement 可能还没变,不加 setTimeout 延迟读取,状态判断就失效。



















