:fullscreen伪类仅在原生全屏API调用时生效,不可靠;真正可信的是document.fullscreenElement配合fullscreenchange事件,并需手动标记CSS模拟全屏状态。

用 :fullscreen 伪类判断视频是否全屏,根本不可靠
:fullscreen 是 CSS 伪类,只在元素**真正通过 API 进入浏览器原生全屏**(如调用 video.requestFullscreen())时才匹配。它不响应 F11 全屏、双击全屏、CSS 变换模拟的“伪全屏”(比如 xgplayer 的 cssFullscreen),也不管视频是否在视口内、是否播放中。直接靠它做状态判断,90% 场景会漏判或误判。
常见错误现象:
- 用户按 F11 进入全屏 →
:fullscreen不触发,样式失效 - 使用
position: fixed; width: 100vw; height: 100vh;模拟全屏 → 完全不进:fullscreen - 竖屏视频启用 xgplayer 的
cssFullscreen→ DOM 结构没变,伪类无感知
真正能用的全屏状态检测:必须读 document.fullscreenElement
浏览器原生全屏的唯一可信信号是 document.fullscreenElement —— 它返回当前处于全屏状态的 DOM 节点,不是则为 null。配合 fullscreenchange 事件监听,才是稳定方案:
document.addEventListener('fullscreenchange', () => {
const isVideoFullscreen = document.fullscreenElement?.nodeName === 'VIDEO';
if (isVideoFullscreen) {
console.log('video 正在原生全屏');
}
});
注意点:
- 不要只检查
document.fullscreen或document.webkitIsFullScreen等布尔属性,它们在部分 Android 浏览器中始终为false,即使已全屏 - 若你全屏的是容器 div(不是 video 元素本身),要检查
document.fullscreenElement === myVideoContainer,而非硬判 nodeName - F11 全屏时,
document.fullscreenElement通常是document.documentElement,不是 video —— 这属于浏览器窗口级全屏,需单独处理
如何区分「原生全屏」和「CSS 模拟全屏」
移动端尤其需要这个判断:xgplayer 的 cssFullscreen: true 本质是用 transform + fixed 把 video 拉满屏幕,DOM 层级没变,document.fullscreenElement 一直是 null。此时得靠 JS 主动标记状态:
做法是:在调用 player.enterCssFullscreen() 前,手动设一个标志位,比如 player.isCssFullscreen = true;退出时置 false。再结合 resize 和 orientationchange 事件校验尺寸比,避免横竖屏切换后状态错乱。
关键逻辑示例:
function isTrulyFullscreen(videoEl) {
// 原生全屏
if (document.fullscreenElement === videoEl) return 'native';
// CSS 全屏(需你主动维护的状态)
if (player.isCssFullscreen) return 'css';
// F11 或其他窗口级全屏
if (document.fullscreenElement === document.documentElement) return 'window';
return null;
}
别忘了退出全屏的兼容写法
仅靠 document.exitFullscreen() 不够,老版本 Chrome/Safari/IE 都要兜底:
function exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
容易被忽略的一点:退出后,document.fullscreenElement 不一定立刻变为 null —— 尤其在 iOS Safari 中有微小延迟。所以状态同步建议放在 fullscreenchange 回调里,而不是紧跟着 exitFullscreen() 后立即读取。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











