配了五年移动端,每次厨房看菜谱手上有东西屏幕就黑了——今天浏览器自己会管了
你有没有遇到过这种情况:在厨房里做饭,手机放在旁边看菜谱,手上沾满了面粉或者油,结果屏幕突然黑了——你得去擦手、点亮屏幕,弄完菜谱又得从头找刚才看到哪了。
这件事,浏览器今天自己会修了。
Screen Wake Lock API——一个在 2025 年 3 月正式进入 Baseline 的 Web API——可以让网页请求系统不要让屏幕变暗或熄灭。Chrome 84、Firefox 126、Safari 16.4(iOS 和 macOS)、Opera、Samsung Internet,现在全部支持了。这个覆盖范围意味着:你在移动端做的 Web 应用,用户点菜谱的时候,屏幕会一直亮着。
这个 API 能做什么
navigator.wakeLock.request(screen) 返回一个 Promise,resolve 成 WakeLockSentinel 对象。如果系统允许,屏幕就会一直亮着。
这个 API 的核心使用场景非常具体:用户需要持续盯着屏幕做一件事,而手指不在屏幕上。
典型的场景:
- 做饭看菜谱:手上全是面粉,没法去点屏幕
- 导航:开车时手机放支架上,不需要触控,但要一直看着路线
- 视频播放:看剧时不想每隔一分钟就去点一下屏幕
- 演示文稿:投影时手机做提词器,屏幕要一直亮着
- 扫码/拍照:设备举着对焦,没法同时点屏幕
一个很多人踩的坑:切标签页锁就丢了
Wake Lock 不是「设一次就永久有效」的东西。浏览器会在页面失去可见性时自动释放锁——这是 spec 里的设计,为了省电。
这意味着:用户从你的菜谱页面切到微信回消息,再切回来时,屏幕锁已经没了。
所以你需要处理 visibilitychange 事件:
let wakeLock = null;
async function requestScreenWakeLock() {
try {
wakeLock = await navigator.wakeLock.request(‘screen’);
} catch (err) {
console.log(‘锁请求失败:’, err.name);
}
}
// 切回来的时候重新请求
document.addEventListener(‘visibilitychange’, async () => {
if (document.visibilityState === ‘visible’) {
await requestScreenWakeLock();
}
});
// 手动释放
async function releaseWakeLock() {
if (wakeLock) {
await wakeLock.release();
wakeLock = null;
}
}
WakeLockSentinel 上还有一个 release 事件,监听它可以在锁被系统意外释放时收到通知——比如低电量时系统强制收回锁。
Safari 的限制和 NoSleep.js 的替代
Safari 16.4 才支持 Wake Lock API——这意味着 iOS 16.4 以下的用户用不了。一个常见的 workaround 是 NoSleep.js:它通过创建一个静音的循环播放视频元素来欺骗系统屏幕在使用中,从而阻止熄屏。这个方案有效,但代价是持续占用媒体解码资源,不是最优解。
对于必须覆盖老版 iOS 的场景,NoSleep.js 可以做降级:
if (‘wakeLock’ in navigator) {
wakeLock = await navigator.wakeLock.request(‘screen’);
} else if (typeof NoSleep !== ‘undefined’) {
noSleep.enable();
}
但如果你面向的是 2024 年以后的用户设备,原生 Wake Lock 的覆盖已经足够好了。
Permissions Policy:为什么有时候请求会失败
如果你的页面在 iframe 里,或者服务器配置了 Permissions-Policy: screen-wake-lock=self,API 请求会抛出 NotAllowedError。检查一下你的 HTTP 响应头:
Permissions-Policy: screen-wake-lock=self
确保这个策略允许当前域名使用 Wake Lock。
电池问题:这不是免费的
屏幕是手机最大的耗电部件。保持屏幕常亮会让电池消耗速度增加 20-40%。这意味着:
- 做饭看菜谱 45 分钟,手机可能从 80% 掉到 50%
- 长时间使用建议插上电源或调低亮度
这个 API 不是让你「让用户一直看屏幕」的借口。它的正确用法是:用户明确进入了一个需要持续盯着屏幕的任务,你就帮他把灯点亮;任务结束或者用户切走了,你就释放锁。
一个判断标准:如果用户不做任何操作,屏幕正常应该多久熄灭?如果那个场景下用户本来就不会让屏幕灭(比如正在看视频、正在导航),那 Wake Lock 是合适的。如果用户只是把页面开着然后去做别的事情,锁会帮他保持屏幕常亮,这不是应该做的事。
和系统锁屏是两码事
这里有一个重要的边界要划清楚:Wake Lock 只阻止屏幕变暗/熄灭,不管系统锁屏。
用户设置了「1 分钟无操作锁屏」,你用 Wake Lock 把屏幕保持常亮,1 分钟后系统依然会弹出锁屏界面要求输入密码。这不是 Wake Lock 的 bug,是它的设计边界——浏览器的 API 不应该能绕过操作系统的安全策略。如果你想阻止系统锁屏,需要在操作系统层面设置,不能靠网页。
结论:这是移动端 Web 的一个小而正确的功能
Screen Wake Lock API 是一个解决具体问题的 API,不是那种「看起来很厉害但不知道用在哪」的东西。做饭看菜谱、导航、演示——这些场景在移动端是真实的高频需求。
现在 Safari 16.4+、Firefox 126+、Chrome/Edge/Opera 全支持,2025 年进入 Baseline 意味着主流浏览器的兼容性已经不是问题。
如果你做的是移动端 Web 应用,在这些场景下加上 Wake Lock 支持,是成本很低但用户感知很明显的一个细节。你需要做的:
- 判断用户进入了需要持续看屏幕的场景(视频播放、导航模式、阅读模式)
- 在进入时调用 navigator.wakeLock.request(‘screen’)
- 处理 visibilitychange 重新请求,处理 release 事件做兜底
- 在场景结束时调用 wakeLock.release()
就这么简单。这个 API 的价值在于它解决的那一小批场景——那些用户真的需要屏幕一直亮着、手却腾不出来的情况。这种场景,Web 以前是做不到的,现在可以了。
评论区
登录后可评论。