跳转到内容

Screen Wake Lock API:保持屏幕常亮

一句话: Screen Wake Lock API——navigator.wakeLock.request('screen')——在你的应用 活跃时防止设备屏幕变暗或锁定。它需要安全上下文,只能在文档可见时获取,且在页面隐藏 (最小化、切换走或被 OS 锁定)时会自动释放。

let wakeLock = null;
async function requestWakeLock() {
try {
wakeLock = await navigator.wakeLock.request('screen');
console.log('Wake lock 已获取');
wakeLock.addEventListener('release', () => {
console.log('Wake lock 已释放');
wakeLock = null;
});
} catch (err) {
// DOMException:请求被拒绝(如电量低)
console.error(`Wake lock 请求失败:${err.name}${err.message}`);
}
}

用例结束时显式释放锁——否则会不必要地消耗电量:

async function releaseWakeLock() {
if (wakeLock) {
await wakeLock.release();
wakeLock = null;
}
}

每当 document.visibilityState 变为 'hidden'——用户切换标签页、最小化浏览器或 设备切换到其他应用——浏览器会自动释放 wake lock。页面再次可见时,锁不会自动恢复, 必须重新获取:

document.addEventListener('visibilitychange', async () => {
if (document.visibilityState === 'visible' && userNeedsWakeLock) {
await requestWakeLock();
}
});

navigator.wakeLock 仅在安全上下文——HTTPS 或 localhost——中可用。在普通 HTTP 下,该属性为 undefined

与摄像头或麦克风访问不同,wake lock 不显示浏览器权限对话框。浏览器可能在电量低的情况 下静默拒绝请求——代码应优雅处理拒绝(上方的 catch 块)。

规范将 'screen' 定义为唯一有效的 wake lock 类型。曾考虑过 'system' 类型(在屏幕 关闭时防止 CPU 睡眠),但当前所有实现均未向网页暴露该类型。

持有 wake lock 会阻止 OS 调暗屏幕,显著增加电量消耗。仅在真正必要时(食谱显示、演示 模式、实时追踪)请求,并在用户完成或离开时始终释放。

当前各浏览器数据请参见 /compatibility/

决策问题 建议行为 理由
食谱查看器、演示、幻灯片? 开始时获取;用户关闭内容时释放。 经典 wake lock 用例——双手占用时防止屏幕超时。
实时追踪或健身应用? 追踪开始时获取;停止时释放。 屏幕必须保持常亮以便用户查看实时数据。
wake lock 应在切换标签页后继续? 不——浏览器自动释放。在 visibilitychange 监听器中重新获取。 这是浏览器有意为之的安全不变量。
需要在后台保持 CPU 活跃(SW 同步)? 使用 Background Sync 或 Periodic Background Sync。 Wake lock 仅限屏幕,且需要可见文档。
电量低——请求失败怎么办? 捕获拒绝;回退到告知用户手动保持屏幕常亮的 UI。 浏览器可能因节能原因拒绝;应用应优雅降级。
  • 通过 HTTPS 提供页面——普通 HTTP 下 navigator.wakeLock 为 undefined。
  • 特性检测:调用 request 前检查 if (!navigator.wakeLock)
  • visibilitychange 监听器中文档再次可见时重新获取锁。
  • 不再需要该功能时显式释放锁。
  • 捕获 request() 的拒绝——浏览器可能在电量低时拒绝。
  • 若无法获取 wake lock,告知用户以便他们手动防止屏幕超时。