
Screen Wake Lock API 不可用时的典型报错
调用 navigator.wakeLock.request() 时如果抛出 NotAllowedError,基本意味着当前上下文不满足激活条件:页面没在前台、没用户手势触发(比如点击/触摸)、协议不是 HTTPS(localhost 除外),或浏览器不支持。Chrome 88+、Edge 88+、Firefox 110+ 支持,Safari 完全不支持——这点必须提前确认,否则代码会静默失败。
必须用用户手势触发 request(),不能 onload 自动调用
Wake Lock 是敏感权限,浏览器强制要求由明确的用户交互启动。以下写法会失败:
// ❌ 错误:页面加载即请求,无用户动作上下文window.addEventListener(‘load’, () => { navigator.wakeLock.request(‘screen’); // NotAllowedError});
正确做法是绑定到按钮点击等事件:
// ✅ 正确:由 click 触发document.getElementById(‘keepAwakeBtn’).addEventListener(‘click’, async () => { try { const wakeLock = await navigator.wakeLock.request(‘screen’); console.log(‘屏幕已锁定’); } catch (err) { console.error(err.name, err.message); // 如 ‘NotAllowedError’ 或 ‘SecurityError’ }});手势必须是“可信任事件”,click、touchend 可行;setTimeout 里模拟点击不行不能在 iframe 中调用,除非主文档已获权限且 iframe 有 allow="wake-lock" 属性
锁屏后需主动释放,否则耗电且影响用户体验
Wake Lock 不会自动释放——页面隐藏、刷新、关闭标签页时系统会回收,但逻辑上应显式释放。常见疏漏是只申请不释放,或未监听页面可见性变化:
立即学习“前端免费学习笔记(深入)”;
let wakeLock = null;const requestWakeLock = async () => { try { wakeLock = await navigator.wakeLock.request(‘screen’); } catch (err) { console.warn(‘无法获取 Wake Lock:’, err.name); }};// 页面切到后台时释放document.addEventListener(‘visibilitychange’, () => { if (document.hidden && wakeLock !== null) { wakeLock.release(); wakeLock = null; }});// 页面卸载前确保释放(如刷新)window.addEventListener(‘beforeunload’, () => { if (wakeLock !== null) { wakeLock.release(); }});不要依赖 pagehide 或 unload 做唯一释放点——它们可能不触发(尤其安卓 PWA 后台运行时)释放后再次调用 request() 会重新获取新锁,无需复用旧对象长期持有(如视频播放超过 30 分钟)可能被系统强制释放,需监听 release 事件做兜底
调试时注意 Chrome 的限制策略和 DevTools 提示
Chrome 在开发者工具中会显示 Wake Lock 状态,但仅限当前标签页活跃且满足条件时。若控制台没报错却没效果,检查:
地址栏是否显示 ?(HTTPS 或 localhost)DevTools → Application → Permissions → Wake Lock 是否为 “Allow”(手动改过一次后才持久)手机端 Chrome 需开启「网站设置 → 权限 → 唤醒锁」,部分厂商 ROM(如华为 EMUI)会额外拦截使用 navigator.wakeLock.getAvailability() 可查当前是否允许申请(返回 Promise),但不反映实时锁状态
实际项目中,别把 Wake Lock 当作保活手段——它只防熄屏,不阻止页面被系统回收或 JS 被暂停。真正需要后台持续运行的场景(如音乐播放),得结合 Background Fetch 或 Service Worker,但那已是另一套机制了。

评论(0)