如何在JavaScript中使用全屏API(并通过“唤醒锁API”使屏幕保持处于唤醒状态)
迟早,大多数前端开发人员都会遇到这样一个问题: "这个内容能覆盖整个屏幕吗?" 无论是幻灯片、视频播放器、信息亭的控制面板、游戏界面、绘图工具,还是教室投影仪上的计时器,当浏览器标签页和地址栏还显示在屏幕边缘时,这些界面看起来总是不完整。 好消息是,浏览器本身提供了解决方案: 全屏API 。不过坏消息是,这个API存在一些问题,在实际使用中很可能会遇到麻烦——比如用户的手势操作、Safari浏览器特有的前缀、某些iPhone设备的不兼容性,以及屏幕在进入全屏状态两分钟后就会自动变暗的问题。 在本教程中,你将学习如何: 将任何元素(或整个页面)设置为全屏显示,然后再恢复正常视图 当用户按下 Es
迟早,大多数前端开发人员都会遇到这样一个问题:"这个内容能覆盖整个屏幕吗?"
无论是幻灯片、视频播放器、信息亭的控制面板、游戏界面、绘图工具,还是教室投影仪上的计时器,当浏览器标签页和地址栏还显示在屏幕边缘时,这些界面看起来总是不完整。
好消息是,浏览器本身提供了解决方案:全屏API。不过坏消息是,这个API存在一些问题,在实际使用中很可能会遇到麻烦——比如用户的手势操作、Safari浏览器特有的前缀、某些iPhone设备的不兼容性,以及屏幕在进入全屏状态两分钟后就会自动变暗的问题。
在本教程中,你将学习如何:
将任何元素(或整个页面)设置为全屏显示,然后再恢复正常视图
当用户按下
Esc键时,确保用户界面仍能保持同步使用
:fullscreen伪类为全屏内容设置样式解决跨浏览器兼容性问题,包括那些仍然不支持全屏功能的平台
利用屏幕唤醒锁API防止屏幕在进入全屏状态后变暗
将所有这些技术整合成一个可重复使用的解决方案
本教程中使用的都是纯JavaScript代码,不需要任何第三方库或复杂的构建流程。你只需要熟悉DOM事件以及async/await语法即可。如果你需要复习这部分内容,freeCodeCamp提供了非常详细的async/await教程,其中涵盖了我们将会用到的所有知识点。
目录
全屏API的工作原理
全屏API非常简单,它提供了三种你每天都会用到的功能:
element.requestFullscreen():请求浏览器使用整个屏幕来显示该元素及其子元素。这个方法会返回一个Promise对象。document.exitfullscreen():退出全屏模式。同样会返回一个Promise对象。document.fullscreenElement:当前处于全屏状态的元素;如果没有全屏元素,则返回null。这个属性是判断“当前是否处于全屏状态”的唯一依据。
此外,document对象还提供了两个相关事件:fullscreenchange(当页面进入全屏模式或退出全屏模式时触发),以及fullscreenerror(当全屏请求失败时触发)。
有一点可能会让人感到惊讶:你可以让任何元素进入全屏模式,而不仅仅是整个页面。如果你将一个 如果想让整个页面进入全屏模式,需要在 关于全屏模式的详细信息,可以参考MDN的全屏API页面,但实际使用时,上述内容已经足够使用了。 让我们从最简单的例子开始:一个可以用来切换页面全屏/非全屏状态的按钮。 按照这种简单的写法,代码就可以正常运行了。因为这两个方法都会返回Promise对象,所以你可以使用 不过,这两种操作也有可能失败。例如,如果浏览器不允许页面进入全屏模式,或者在页面根本没有处于全屏状态时尝试调用 这里有一个需要注意的地方,也是在Stack Overflow上最常被问到问题的地方:你不能自动让页面进入全屏模式。无论是在页面加载时、定时器触发后,还是响应某个网络事件时,都不允许自动进入全屏模式。 这是有意为之。如果没有这样的设计,任何页面在加载完成后都可能占据整个屏幕,而正是这种行为才是钓鱼页面所希望看到的。 在实际开发中,这对你的代码来说意味着以下两点: 始终要通过与用户操作相关的事件处理器来触发全屏模式:例如 在调用 应该先调用 一种常见且很自然的做法是使用键盘快捷键来实现与按钮相同的功能: 有兩点我在第一次开发时犯错了,现在把这些经验分享给大家。 首先,要确保全屏界面本身也可以通过键盘访问:给它设置 其次,要检查你设置的快捷键是否会导致页面出现意外的反应。我曾经开发过一个“黑客模拟器”页面,在这个页面上,按下任何按键都会生成虚假的终端输出信息,包括 说到 由于用户可以通过一些你的代码无法控制的方式退出全屏模式(比如按下 相反,应该将 这个监听器能够覆盖所有进出全屏模式的场景,包括那些并非由用户主动触发的情况。同时,它也是暂停动画、恢复游戏循环或释放唤醒锁的理想时机。 CSS为全屏状态提供了两种自定义方式。 乍看之下, 一个小技巧:如果你想要让整个页面进入全屏模式,应该将背景颜色设置在 多年来,全屏API在Chrome、Edge和Firefox中一直被视为标准功能。而Safari则还在进一步完善这一功能。 Safari直到2023年春季的16.4版本才在macOS和iPadOS上提供了不带前缀的API。在此之前,它使用的是 现在,在所有的浏览器中, 这个问题确实会让很多人遇到麻烦。在撰写本文时,iPhone上的Safari浏览器并不支持对任意元素应用全屏模式——只有 你有两种可行的解决方案: 采用“伪全屏”方案:使用 建议用户“添加到主屏幕”:如果你的Web应用允许从主屏幕直接启动,并且在应用的manifest文件中设置了 无论你选择哪种方案,都不要仅仅依赖功能检测来判断是否可以使用全屏模式。 我的经验是:直接尝试使用真正的API,如果请求被拒绝,那就立即启用CSS中的备用方案。 在手机上,我会采取更极端的措施:根本不调用这个API,即使在Android系统上这个API技术上是可行的。由于滚动时地址栏会重新出现,再加上系统的滑动操作机制,在小屏幕触摸设备上,使用固定的覆盖层比真正的全屏效果更加稳定、更容易预测用户的行为。实际上,iPhone的Safari浏览器也是采用这种方式的,所以也就不需要再为这种情况编写额外的测试代码了。 在决定自己是否需要使用这些功能之前,你可以先查看Can I use网站上的当前支持情况表格。 你已经打造出了非常出色的全屏体验。用户放松下来享受这种体验……但90秒钟后,屏幕就会变暗并锁定,因为操作系统没有检测到任何操作,从而认为没有人在使用设备。 对于视频元素来说,浏览器会自动处理这个问题;但对于其他内容(比如倒计时、幻灯片展示、canvas动画、食谱页面或乐谱页等),你就需要使用Screen Wake Lock API了。这个API在2024年就已经被所有主流浏览器支持(Chrome 84及以上版本、Safari 16.4及以上版本、Firefox 126及以上版本),并且在2025年成为了所有浏览器都应支持的基线功能,因此你现在就可以直接使用它了,而无需额外添加任何兼容代码。 这个API只需要调用一次,并且它是基于Promise机制设计的: 有 three 条规则需要牢记: 这个API必须在安全的环境中使用。它仅通过 HTTPS 或 当页面被隐藏时,浏览器会自动释放锁。如果用户切换标签页、最小化窗口或锁定手机,那么当页面再次显示出来时,锁并不会自动重新启用。你需要再次调用这个API来重新申请锁。 好在,全屏API已经提供了一个完美的信号来指示“是否有内容正在显示”:这个信号就是`fullscreenchange`事件。当用户进入全屏模式时,就请求锁定屏幕;当他们退出全屏模式时,就释放这个锁。 不过,`fullscreenchange`并不是唯一的可用信号。我们可以将“唤醒锁”视为与某个特定的“活动”相关联,而不是与某种显示模式相关联。例如,在一个倒计时定时器中,我会在倒计时开始时请求锁定屏幕,而在倒计时结束或暂停时释放这个锁——因为没有人希望定时器在倒计时进行到90秒的时候突然变暗。在一个播放雨声的应用程序中,锁定屏幕的操作也会随着音频的播放或暂停而相应地启动或停止。 其背后的机制其实是相同的,只是我们需要根据具体的应用场景来决定“现在是否应该保持屏幕处于唤醒状态”这个判断标准而已。 以下是将所有这些做法整合在一起的具体方案:通过键盘快捷键来切换全屏模式;让“唤醒锁”根据当前的全屏状态自动进行相应的操作;确保用户无论以何种方式离开当前界面,UI都能保持同步;同时也为那些不支持相关功能的浏览器提供了备用解决方案。 相应的CSS代码如下: 这段CSS代码仅有大约六十行,但它正是我在生产环境中实际使用的核心代码。我会将每次全屏模式的切换记录为分析数据,因为对于那些以屏幕展示为核心功能的网站来说,这种切换行为本身就代表着一次转化机会,而正是这段代码触发了这一转换过程。 例如,blankscreen.io上的黑屏页面就是利用了这段代码实现的——这个页面的功能就是将整个屏幕显示为纯黑色背景,用户点击按钮或按下F键时进入全屏模式,指针会隐藏起来;只要页面还在显示,就会保持全屏状态,而按下Esc键后页面会立即恢复正常显示。如果在iPhone上打开这个页面,上面提到的备用方案也会被自动启用。 在实际应用中,这种模式也是通用的:用户只需点击一次按钮或按下F键,整个屏幕就会变成黑色,并且会一直保持全屏状态,直到用户按下Esc键才会恢复正常显示。 一旦掌握了这种模式,那么将其应用于计时器、幻灯片展示或者canvas实验中,就只需要将想要覆盖整个屏幕的元素添加到相应的代码中即可。 在正式发布产品之前,请先仔细阅读这份清单。其中每一条内容都是我曾经遇到过问题的地方: 需要用户进行操作才能进入全屏模式:不要在页面加载时、通过计时器触发,也不应在执行耗时较长的 不要自行检测屏幕状态:应该直接使用 不能阻止用户按下Esc键:设计时必须考虑到用户随时可能退出全屏模式这一情况。 Safari浏览器较旧版本要求方法名和事件名前加上 iPhone上的Safari浏览器没有专门的全屏元素:需要通过 检查你设置的快捷键是否与页面本身提供的按键冲突:如果应用程序需要使用某些按键来控制全屏模式的切换,那么应该让这些快捷键专门用于进入全屏模式,而退出全屏模式仍然使用Esc键。 要确保在全屏模式下,键盘操作依然可用:需要设置 使用唤醒锁功能时需要HTTPS连接:在节省电池的模式下,系统可能会拒绝使用唤醒锁;当页面被隐藏时,唤醒锁也会自动失效。因此需要在 一旦导致唤醒锁的原因消失,就立即释放它: 在全屏模式下,应该为 全屏API正是那种看似简单,但实际上蕴含着诸多复杂机制的浏览器功能之一。 它的核心部分( 只需采用上面提到的那套六十行代码结构,将自己需要的元素添加进去,就可以为各种应用场景——从演示文稿到游戏——打造出适合实际使用的全屏体验。 祝编码愉快! 乱序HTML流式传输这种由前端框架推广开来的一种用户体验技术,能够让用户在页面尚未完全加载完毕之前就快速查看内容并与其进行交互。这项技术正在被越来越多的网页浏览器所采用。目前,浏览器会在数据到达时立即对相关代码进行修补;开发者既可以使用声明式的HTML语法,也可以利用相应的JavaScript API来实现这一功能。该功能已在Chrome 151版本中正式启用。 作者:布鲁诺·库里奥尔 功能开关是团队在部署过程中最强大的工具之一。它们将 部署 与 发布 分离开来,这意味着你的持续集成/持续交付流程可以在每次代码合并时都将更新推送到生产服务器上,但只有当你明确启用这些功能开关时,用户才会看到新的变化。 “部署”是一个技术性操作,而“发布”则是一项产品决策。正是这种分离机制,使得本文中讨论的诸多内容成为可能。 然而,如果实现不当,功能开关反而会带来技术债务、测试难题以及运行时的复杂性。在这篇文章中,你将学习到实施功能开关的核心方法——从简单的布尔值切换,到基于百分比的比例化部署方案,再到针对不同用户群体的功能启用策略,同时还会了解相关的生命周期管理方法及应避免的错误做法。以下就是 Gradio就是这样一种Python库,它让你不禁思考:为什么构建Web界面一开始就会变得如此复杂呢? 你可能已经有过这样的经历:你编写了一个Python程序,它运行得很好;你的机器学习模型能够生成预测结果;你的AI应用程序也能给出相当不错的答案;你的数据处理脚本也完全按照你的预期完成了工作。 然后,有人想要使用这个程序。 你把Python文件发给他们,他们询问如何运行这个程序,你告诉他们需要安装Python环境。 接着他们又发现需要特定版本的Python,还需要相关的依赖库,之后还得执行`pip install`命令……然而,最终还是会出现各种问题。 于是,原本让你充满期待想要分享的这个应用 过去,开发应用程序往往就像在没有任何说明书的情况下组装家具,而且还会缺少一半的螺丝。如今,像Lovable这样的人工智能工具可以帮助你用简单明了的语言描述自己的需求,从而将一个想法转化为可运行的网页应用。 这确实很令人兴奋——但同时也意味着一种责任。 Lovable能帮助你快速行动、尝试各种想法,并创造出实用的软件。不过,速度绝不能取代周密的思考。由人工智能生成的程序可能会存在安全问题、导致用户使用体验混乱、包含不准确的信息,或者其代码在演示环境中可以正常运行,但在实际使用中却会出故障。 在这份指南中,你将学习到如何在实际使用Lovable的过程中兼顾安全性、隐私性、可访问性以及用户的安全。我document.documentElement(即元素)上调用相应的方法。进入与退出全屏模式
<button id="fs-toggle">>全屏模式<\/button>const toggleBtn = document.getElementById('fs-toggle');
async function toggleFullscreen() {
if (!document.fullscreenElement) {
// 页面尚未处于全屏状态,因此尝试进入全屏模式。
await document.documentElement.requestFullscreen();
} else {
// 页面已经处于全屏状态,因此退出全屏模式。
await document.exitFullScreen();
}
}
toggleBtn.addEventListener('click', toggleFullscreen);
await来等待这些操作的完成,从而确保在后续代码执行之前,全屏模式的切换已经完成。exitFullscreen()方法,都会导致操作失败。因此,在实际开发中,应该使用try/catch语句来处理这些可能的错误情况,以免错误信息出现在控制台里:async function toggleFullscreen() {
try {
if (!document.fullscreenElement) {
await document.documentElement.requestFullScreen();
} else {
await document.exitFullscreen();
}
} catch (err) {
console.warn(`全屏模式切换失败:${err.name} – ${err.message}`);
}
}
用户手势规则
requestFullscreen()方法只有在页面处于规范中所谓的短暂激活状态时才能被调用。这种状态是指用户在真正与页面进行交互之后的一段短时间内。如果超出了这个时间窗口,该方法就会失败,大多数浏览器会显示一条提示信息,内容大概是“API只能通过用户手势来触发”。
click、keydown、pointerup 等事件。requestFullscreen() 之前,千万不要对那些需要较长时间才能完成的操作使用 await。如果你先执行 await fetch(...),那么当你尝试进入全屏模式时,激活窗口可能已经失效了。
requestFullscreen(),然后再执行耗时的操作;否则,在你请求进入全屏模式之前,激活窗口就会关闭。document.addEventListener('keydown', (e) => {
// 当用户在输入框中输入内容时,忽略快捷键操作。
if (e.target.matches('input, textarea, [contenteditable]')) return;
if (e.key === 'f' || e.key === 'F') {
e.preventDefault();
toggleFullscreen();
}
});
tabindex="0",并且要让按 Enter 或 Space 键时的行为与点击按钮时的效果完全相同。否则,使用键盘的用户就会遇到一个他们根本不知道存在的“按钮”。F 键。在最初的几天里,用户在使用这个功能时,每次按下 F 键,全屏模式都会立即关闭。后来我发现,只需要将 F 键设置为仅用于进入全屏模式,而退出全屏模式则继续使用 Esc 键即可解决问题。Esc 键,你需要注意的是:不要自己处理这个键的操作。所有浏览器都会在用户按下 Esc 键时自动退出全屏模式,你无法阻止这一行为。这是为了保障用户的操作安全性而设计的机制。不过,你可以针对这一行为做出相应的响应,这将是下一节的内容。让你的用户界面与
fullscreenchange 事件保持同步Esc 键、使用浏览器的退出按钮,或者在移动设备上切换应用程序),因此你绝对不应该在自己的变量中记录全屏状态。否则,这些状态就会变得不一致。document.fullscreenElement视为判断全屏状态的依据,并在fullscreenchange事件触发时更新用户界面:function syncFullscreenUI() {
const isFullscreen = Boolean(document.fullscreenElement);
toggleBtn.textContent = isFullscreen ? '退出全屏' : '进入全屏';
toggleBtn.setAttribute('aria-pressed', String(isFullscreen));
document.body.classList.toggle('is-fullscreen', isFullscreen);
}
document.addEventListener('fullscreenchange', syncFullscreenUI);
document.addEventListener('fullscreenerror', () => {
console.warn('无法进入全屏模式。');
});
全屏内容的样式设置
:fullscreen伪类用于匹配当前处于全屏状态的元素。浏览器会自动应用一种默认样式,使该元素占据整个视口,但通常你还是需要自行控制背景颜色及内容溢出显示等细节::fullscreen {
background: #000;
overflow: hidden;
cursor: none; /* 在全屏状态下隐藏鼠标指针 */
}
cursor: none这条代码似乎只是为了美观而存在的,但当你在一个OLED显示屏上显示纯黑色页面时,这个设置就会显得非常重要:因为此时除了鼠标指针外,屏幕上其他地方都处于熄灭状态,而只有指针是亮着的。因此,在全屏模式下隐藏鼠标指针,就能让屏幕看起来像是“完全关闭了”,而不是“中间有一个小白箭头”。::backdrop伪元素用于设置全屏元素背后的背景颜色。只有当全屏元素的尺寸无法覆盖整个屏幕时(例如某些固定宽高比的元素),这个属性才会有用,而且它正是用来控制页面边缘的边框颜色的。html元素上,而不是body元素上。因为在全屏模式下,实际显示的是html元素,而在某些浏览器中,如果只设置body元素的背景颜色,那么在页面切换过程中,边缘会留下一条颜色不一致的窄带。跨浏览器的注意事项
旧版本的Safari需要添加
webkit前缀webkitRequestFullscreen()、webkitExitFullscreen()、webkit fullscreenElement以及webkitfullscreenchange事件。除非你打算忽略那些使用了三年旧版Safari的系统,否则添加一个兼容性层仍然是很有必要的。const fs = {
get element() {
return document.fullscreenElement ?? document.webkitFullscreenElement ?? null;
},
get enabled() {
return Boolean(document.fullscreenEnabled ?? document.webkitFullscreenEnabled);
},
request(el = document.documentElement) {
if (el.requestfullscreen) return el.requestFullscreen();
if (elwebkitRequestFullscreen) return Promise.resolve(el.webkitRequestFullscreen());
return Promise.reject(new Error('不支持全屏模式'));
},
exit() {
if (document.exitFullscreen) return document.exitFullscreen();
if (document.webkitExitFullscreen) return Promise.resolve(document.webkitExitFullscreen());
return Promisereject(new Error('不支持全屏模式'));
},
};
// 同时监听这两个事件名称,这样旧版本的Safari也能保持同步。
['fullscreenchange', 'webkit fullscreenchange'].forEach((evt) =>
document.addEventListener(evt, syncFullscreenUI)
);
fs.request()和fs.exit()都会返回一个Promise对象,因此你的其他代码并不需要关心具体使用的是哪一个方法。(你可以参考screenfull.js这个库。它是一个不错的工具,但已经被宣布为“功能完备”的版本,并且不再有新的开发内容了。上面那些代码其实就是这个库所提供的一切功能。)iPhone Safari完全不支持元素全屏模式
标签才能使用全屏功能。iPad和Mac上是可以使用这个功能的,但在手机上,document.fullscreenEnabled的值为false,而且requestFullscreen>方法。iOS上的Chrome和Firefox浏览器也受到同样的限制,因为它们必须使用Safari的引擎。
position: fixed; inset: 0来定位你的元素,并隐藏浏览器的界面。虽然这样无法去除Safari的地址栏,但在滚动时地址栏会自动隐藏,对于大多数应用来说,这种效果已经足够好了。"display": "standalone"属性,那么这个应用在运行时就不会显示浏览器的界面。目前,在iPhone上,这是实现真正的全屏显示的唯一方法。document.fullscreenEnabled只能告诉你这个API是否存在,但在实际运行过程中,请求仍然可能会被拒绝——比如在没有allowfullscreen>属性的iframe中,或者在浏览器政策限制的情况下,又或者是因为你测试过的其他浏览器有自己的判断标准。function enterFullscreen(el) {
if (fs.enabled) {
return fs.request(el).catch(() => {
// API可用,但被拒绝了——此时就改用固定的覆盖层来达到全屏效果。
document.body.classList.add('pseudo-fullscreen');
});
}
document.body.classList.add('pseudo-fullscreen');
return Promise.resolve();
}
利用Wake Lock API保持屏幕处于唤醒状态
let wakeLock = null;
async function requestWakeLock() {
if (!('wakeLock' in navigator)) return; // 如果不支持该API,就会无声地失败
try {
wakeLock = await navigator.wakeLock.request('screen');
wakeLock.addEventListener('release', () => {
// 当操作系统或浏览器释放了锁时,就需要将wakeLock设置为null。
wakeLock = null;
});
} catch (err) {
// 如果请求被拒绝,通常是因为设备处于节能模式。
console.warn(`Wake lock failed: ${err.name} – ${err.message}`);
}
}
async function releaseWakeLock() {
if (wakeLock) {
await wakeLock.release();
wakeLock = null;
}
}
localhost 提供。document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible' && amp; shouldStayAwake()) {
requestWakeLock();
}
});
整体归纳
const toggleBtn = document.getElementById('fs-toggle');
let wakeLock = null;
/* ---------- 全屏兼容层 ---------- */
const fs = {
get element() {
return document.fullscreenElement ?? document.webkitFullscreenElement ?? null;
},
get enabled() {
return Boolean(document.fullscreenEnabled ?? document.webkitFullscreenEnabled);
},
request(el = document.documentElement) {
if (el.requestFullscreen) return el.requestFullscreen();
if (elwebkitRequestFullscreen) return Promise.resolve(el.webkitRequestFullscreen());
return Promise.reject(new Error('全屏功能不受支持'));
},
exit() {
if (document.exitFullscreen) return document.exitFullscreen();
if (document.webkitExitFullscreen) return Promise.resolve(document.webkitExitFullscreen());
return Promisereject(new Error('全屏功能不受支持'));
},
};
/* ---------- 唤醒锁 ---------- */
async function requestWakeLock() {
if (!('wakeLock' in navigator) || wakeLock) return;
try {
wakeLock = await navigator.wakeLock.request('screen');
wakeLock.addEventListener('release', () => { wakeLock = null; });
} catch (err) {
console.warn(`唤醒锁操作失败:${err.name}`);
}
}
async function releaseWakeLock() {
if (!wakeLock) return;
await wakeLock.release();
wakeLock = null;
}
/* ---------- 切换全屏模式 ---------- */
async function toggleFullscreen() {
const pseudo = document.body.classList.contains('pseudo-fullscreen');
try {
if (pseudo) {
document.body.classList.remove('pseudo-fullscreen');
onFullscreenChange();
} else if (!fs.element) {
await fs.request();
} else {
await fs.exit();
}
} catch (err) {
// 如果API调用失败,就回退到默认方案。
document.body.classList.add('pseudo-fullscreen');
onFullscreenChange();
}
}
/* ---------- 保持所有状态同步 ---------- */
function onFullscreenChange() {
const active = Boolean(fs.element) || document.body.classList.contains('pseudo-fullscreen');
toggleBtn.textContent = active ? '退出全屏模式' : '进入全屏模式';
toggleBtn.setAttribute('aria-pressed', String(active));
document.body.classList.toggle('is-fullscreen', active);
// 只要我们处于全屏模式,屏幕就应该保持唤醒状态。
if (active) requestWakeLock(); else releaseWakeLock();
}
['fullscreenchange', 'webkit fullscreenchange'].forEach((evt) =>
document.addEventListener(evt, onFullscreenChange)
);
// 如果标签页在用户进入全屏模式后又被隐藏了,然后再重新显示出来,就需要重新获取屏幕锁定权限。
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible' && fs.element) requestWakeLock();
});
/* ---------- 连接各个组件 ---------- */
toggleBtn.addEventListener('click', toggleFullscreen);
document.addEventListener('keydown', (e) => {
if (e.target.matches('input, textarea, [contenteditable]')) return;
if (e.key === 'f' || e.key === 'F') { e.preventDefault(); toggleFullscreen(); }
});
// 对于不支持全屏功能的平台(比如iPhone上的Safari浏览器),在用户第一次点击按钮时,就会直接进入伪全屏模式——因此不需要进行用户代理检测。另外,在移动设备上,当设备方向发生改变时,视口的大小会在事件触发之后才发生变化,所以需要稍后重新计算画布的尺寸或布局。
const resizeStage = () => { /* 重新调整屏幕内容的布局 */ };
window.addEventListener('orientationchange', () => setTimeout(resizeStage, 100));
html { background: #000; }
:fullscreen { overflow: hidden; cursor: none; }
:fullscreen::backdrop { background: #000; }
/* 为不支持全屏功能的浏览器提供的备用方案 */
body.pseudo-fullscreen .app { position: fixed; inset: 0; }
body.pseudo-fullscreen .chrome { display: none; }
快速检查清单
await语句后自动进入全屏模式。document.fullscreenElement来获取当前的全屏状态,并监听fullscreenchange>事件来进行变化检测。webkit前缀:需要注意这一点。document.fullscreenEnabled来检测这一功能,如果系统拒绝支持全屏模式,就应该将其作为备用方案来处理,而不仅仅是显示控制台警告。tabindex="0",并且确保用户可以通过按Enter键或空格键来操作屏幕。visibilitychange>事件发生时重新请求使用唤醒锁。html元素设置背景颜色,而不仅仅是body元素。结论
requestFullscreen()、exitFullscreen()、fullscreenElement以及fullscreenchange事件)确实相当简单。真正的难点在于:必须遵守用户的操作习惯,准确反映界面的实际状态,妥善处理Safari浏览器的历史记录功能,并且要记住——如果屏幕在两分钟后又恢复了正常显示状态,那么“全屏模式”也就只完成了一半的任务而已。fullscreenchange事件将这两项技术结合在一起使用,就能确保整个系统的流畅性与稳定性。相关文章
乱序HTML流式传输技术正逐渐从JavaScript框架中转移到浏览器本身中。
如何利用功能标志来实现安全、渐进式的功能推出
如何使用Python中的Gradio:一本从初学者到高级用户的完整指南
如何负责任地使用Lovable产品