Promise 封装全屏切换的核心是监听 fullscreenchange 事件并实时校验 document.fullscreenElement 状态,结合超时兜底和错误捕获,确保 requestFullscreen() 和 exitFullscreen() 的异步操作可链式确认、可靠响应。

用 Promise 封装全屏切换,核心是监听 fullscreenchange 事件并结合 document.fullscreenElement 的状态变化做确认,避免轮询或固定延时。
封装 requestFullscreen 并返回 Promise
现代浏览器中,element.requestFullscreen() 本身是同步触发、异步生效的。它不返回 Promise,但会触发后续事件,因此需手动包装:
- 调用
requestFullscreen(),捕获可能的拒绝(如用户未交互、跨 iframe 限制等) - 监听
document上的一次性fullscreenchange事件 - 在事件回调中检查
document.fullscreenElement:存在则 resolve,为null则 reject(表示退出全屏或请求失败) - 设置超时兜底(例如 3s),防止事件丢失或静默失败
示例代码:
function enterFullscreen(element = document.documentElement) {
if (!element.requestFullscreen) {
return Promise.reject(new Error('Fullscreen API not supported'));
}
const handleSuccess = () => {
cleanup();
if (document.fullscreenElement) {
resolve();
} else {
reject(new Error('Fullscreen activation failed'));
}
};
const handleError = (err) => {
cleanup();
reject(err);
};
const cleanup = () => {
document.removeEventListener('fullscreenchange', handleSuccess);
document.removeEventListener('fullscreenerror', handleError);
clearTimeout(timeoutId);
};
const promise = new Promise((resolve, reject) => {
document.addEventListener('fullscreenchange', handleSuccess);
document.addEventListener('fullscreenerror', handleError);
const timeoutId = setTimeout(() => {
cleanup();
reject(new Error('Fullscreen request timed out'));
}, 3000);
element.requestFullscreen()
.catch(handleError); // 捕获早期拒绝(如权限问题)
});
return promise;
}
退出全屏也应返回 Promise
document.exitFullscreen() 同样是异步的,需同样方式封装:
立即学习“Java免费学习笔记(深入)”;
- 调用
exitFullscreen(),监听fullscreenchange - 事件触发后检查
document.fullscreenElement === null - 成功退出才 resolve,否则 reject
function exitFullscreen() {
if (!document.exitFullscreen) {
return Promise.reject(new Error('Fullscreen API not supported'));
}
const promise = new Promise((resolve, reject) => {
const handleExit = () => {
document.removeEventListener('fullscreenchange', handleExit);
if (document.fullscreenElement === null) {
resolve();
} else {
reject(new Error('Failed to exit fullscreen'));
}
};
document.addEventListener('fullscreenchange', handleExit);
document.exitFullscreen().catch(reject);
});
return promise;
}
组合使用:确保状态可链式确认
实际业务中常需“进入 → 执行操作 → 退出”,用 Promise 链或 async/await 可清晰表达依赖和错误处理:
- 用
await enterFullscreen()确保已进入再继续 - 若中途出错(如用户拒绝),后续逻辑不会执行
- 退出时同样 await,保证清理完成后再跳转或重绘
示例:
async function toggleToFullscreen() {
try {
await enterFullscreen(videoEl);
console.log('✅ Now in fullscreen');
// 执行全屏专属逻辑(如播放、UI 适配)
videoEl.play();
// …… 用户操作后
await exitFullscreen();
console.log('✅ Back to normal');
} catch (err) {
console.error('❌ Fullscreen failed:', err.message);
}
}
注意兼容性与常见陷阱
不同浏览器前缀已基本废弃(Chrome 71+、Firefox 64+、Safari 12.1+ 均支持无前缀 API),但仍需留意:
-
必须由用户手势触发(如 click、touchend),否则
requestFullscreen会直接 reject -
iFrame 需显式允许:设置
<iframe allow="fullscreen"> -
移动端行为差异:部分 Android 浏览器不支持 true 全屏,仅进入“沉浸式”模式,
fullscreenElement可能仍为null -
不要依赖屏幕尺寸变化事件:用
fullscreenchange,而非resize,后者不可靠且非因果关系


















