Screen Wake Lock API 仅 Chrome 84+、Edge 84+、Firefox 120+ 支持,Safari 完全不支持;需先检测 'wakeLock' in navigator,且 request() 必须在用户手势中调用,仅接受 'screen' 参数,须手动 release() 防耗电。

Screen Wake Lock API 不支持所有浏览器,先检查兼容性再写逻辑
Chrome 84+、Edge 84+ 和 Firefox 120+ 支持 navigator.wakeLock,但 Safari 完全不支持(截至 iOS 17.5 / macOS 14.5),且 Android WebView 表现不稳定。调用前必须显式检测:
if ('wakeLock' in navigator) { ... }否则会直接抛出 ReferenceError。别在 try/catch 里盲目调用——错误发生在访问属性阶段,不是 request() 阶段。请求 Wake Lock 必须在用户手势触发的上下文中
这是硬性限制:只有点击、触摸、空格键、Enter 键等可验证的用户激活事件中才能调用 wakeLock.request()。自动播放视频、定时器、DOMContentLoaded 或 load 事件里调用会立即拒绝,Promise 返回 DOMException: Permission denied。
button.addEventListener('click', async () => {
try {
wakeLock = await navigator.wakeLock.request('screen');
} catch (err) {
console.error(err.name); // 可能是 'NotAllowedError' 或 'SecurityError'
}
});
- 不能在
setTimeout(() => wakeLock.request(), 100)中绕过 - 不能在
fetch().then(() => wakeLock.request())中延迟调用 - 移动端需注意:
touchstart比click更可靠(避免 300ms 延迟导致上下文丢失)
释放锁要主动且及时,否则耗电严重
wakeLock.release() 不会自动触发,也不受页面隐藏影响——即使用户切到其他标签页或锁屏,锁依然生效。必须在明确的退出场景下手动释放:
// 页面卸载时清理
window.addEventListener('beforeunload', () => wakeLock?.release());
// 或业务逻辑结束时
function stopPresentation() {
wakeLock?.release();
wakeLock = null;
}
- 不要依赖
visibilitychange事件自动释放:用户可能只是临时切走,回来还要继续使用 - 若使用
AbortSignal控制生命周期,注意信号 abort 后仍需显式调用release() - 未释放的锁会导致设备持续亮屏,实测 Android 旧机型 10 分钟内掉电超 15%
“screen” 类型是唯一可用值,别传错字符串
navigator.wakeLock.request() 目前只接受 'screen' 字符串参数,传 'display'、'monitor' 或空字符串都会报 TypeError: Failed to execute 'request' on 'WakeLock': Invalid wake lock type。规范中曾提过 system 类型(防休眠),但尚未被任何浏览器实现。
// ✅ 正确
await navigator.wakeLock.request('screen');
// ❌ 全部报错
await navigator.wakeLock.request('display');
await navigator.wakeLock.request('');
await navigator.wakeLock.request('system');目前没有 polyfill 方案,Safari 用户只能降级为提示“请手动保持屏幕常亮”并引导设置系统级选项。
真正麻烦的是混合场景:比如一个 WebRTC 视频会议页,既要锁屏又要防止系统休眠,还得适配 Safari。这时候得拆开处理——wakeLock 管屏幕,后台心跳或音频播放模拟活动管系统休眠,而 Safari 用户只能放弃锁屏,靠 UI 提示和文档说明兜底。



















