浏览器全屏状态切换本身同步,但监听需用异步的fullscreenchange事件;可用Promise封装等待下一次变更或获取当前状态,持续监听则应使用事件机制而非Promise。

浏览器全屏状态切换(如用户按 F11、点击全屏按钮、调用 requestFullscreen() 或退出全屏)本身是同步触发的,但监听其变化需通过 fullscreenchange 事件,该事件是异步的、无返回值的。Promise 无法“直接包装”这个持续监听过程,但可以用来封装一次性的全屏状态获取或首次状态变更等待。关键在于明确目标:你是想「等待下一次全屏切换发生」,还是「获取当前全屏状态并确保 DOM 已响应」?下面分场景说明实用做法。
等待下一次全屏状态变更(推荐 Promise 封装)
这是最常见且适合 Promise 的场景:你希望代码暂停执行,直到用户进入或退出全屏。利用 addEventListener + once: true,配合 Promise 的 resolve,可干净地等待一次事件:
- 监听
document上的fullscreenchange事件,使用{ once: true }确保只触发一次 - 在回调中检查
document.fullscreenElement判断当前是否处于全屏 - 将结果(
true或false)作为 Promise 的 resolve 值
示例代码:
function waitForFullscreenChange() {
return new Promise(resolve => {
const handler = () => {
resolve(!!document.fullscreenElement);
document.removeEventListener('fullscreenchange', handler);
};
document.addEventListener('fullscreenchange', handler, { once: true });
});
}
// 使用示例
async function handleFullscreen() {
console.log('等待全屏状态变化...');
const isFullscreen = await waitForFullscreenChange();
console.log('当前是否全屏:', isFullscreen); // true 或 false
}
获取当前全屏状态(无需 Promise,但可 Promise 化以统一接口)
document.fullscreenElement 是同步可读属性,直接访问即可。如果你的代码逻辑统一依赖 Promise 链(比如和其它异步操作组合),可将其包装为已解决的 Promise:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不推荐为纯同步读取强行套 Promise,但若需兼容异步流程,可用
Promise.resolve() - 注意:该值反映调用时的瞬时状态,不保证后续不会立刻变化
示例:
function getCurrentFullscreenState() {
return Promise.resolve(!!document.fullscreenElement);
}
// 后续可与其他 Promise 组合
Promise.all([
fetch('/api/data'),
getCurrentFullscreenState()
]).then(([data, isFullscreen]) => {
console.log('数据加载完成,当前全屏状态:', isFullscreen);
});
监听持续的全屏状态变化(不适合 Promise,应使用事件或自定义 Observable)
如果需要长期响应每次全屏切换(例如更新 UI 按钮图标、调整布局),Promise 不适用——它只能 resolve 一次。此时应回归原生事件机制:
- 用
document.addEventListener('fullscreenchange', handler)注册长期监听器 - 在 handler 中根据
document.fullscreenElement更新状态或触发业务逻辑 - 记得在组件卸载或不需要时调用
removeEventListener避免内存泄漏
简单封装成可取消的监听器(类 Promise 风格,但返回取消函数):
function onFullscreenChange(handler) {
const fn = () => handler(!!document.fullscreenElement);
document.addEventListener('fullscreenchange', fn);
return () => document.removeEventListener('fullscreenchange', fn);
}
// 使用
const unsubscribe = onFullscreenChange(isFullscreen => {
toolbarButton.textContent = isFullscreen ? '退出全屏' : '进入全屏';
});
// 后续可取消
// unsubscribe();
注意事项与兼容性补充
实际使用中需注意以下细节:
-
fullscreenchange事件在 Safari 中可能触发两次(进入/退出各一次),建议始终以document.fullscreenElement为准,而非事件类型 - 部分旧浏览器使用带前缀的属性(如
webkitIsFullScreen、mozFullScreenElement),现代项目建议用 detect-fullscreen 等轻量库处理兼容性 - 调用
requestFullscreen()本身返回 Promise(Chrome 71+、Firefox 69+),可用于链式等待「请求成功后是否真正进入全屏」,但要注意该 Promise 只表示 API 调用是否被接受,不代表最终状态(用户可能拒绝权限或中途退出)

















