编程 H5 移动端保持屏幕常亮:Wake Lock API 实战指南

2025-08-16 09:10:24 +0800 CST views 25

H5 移动端保持屏幕常亮:Wake Lock API 实战指南

在移动端 H5 应用中,很多场景都需要让屏幕保持常亮,例如视频播放、运动计步、电子书阅读、远程监控等。如果设备进入睡眠状态,不仅影响用户体验,还可能导致关键操作中断。过去,我们依赖 NoSleep.js 这类库来实现屏幕常亮,但现代浏览器已经提供了官方 Wake Lock API,让我们可以更高效、安全地控制屏幕唤醒状态。

本文将详细介绍 Wake Lock API 的使用方法、兼容性问题以及实战示例。


1. 检测浏览器是否支持 Wake Lock

在使用 Wake Lock API 前,首先需要判断当前浏览器是否支持该功能:

const canWakeLock = () => 'wakeLock' in navigator;

if (canWakeLock()) {
    console.log('当前浏览器支持 Wake Lock API');
} else {
    console.warn('当前浏览器不支持 Wake Lock API,需要使用 polyfill 或 NoSleep.js');
}

⚠️ 注意:截至目前,Chrome 85+ 支持该 API,而 Safari 尚未支持。在 iOS 端,我们仍需使用 polyfill 或 NoSleep.js。


2. 请求屏幕唤醒锁

Wake Lock API 提供了 navigator.wakeLock.request() 方法来请求屏幕常亮状态,它返回一个 WakeLockSentinel 对象:

let wakeLock = null;

const requestWakeLock = async () => {
    try {
        wakeLock = await navigator.wakeLock.request('screen');
        console.log('Wake Lock 已激活,屏幕将保持常亮!');
    } catch (err) {
        console.error(`无法获取 Wake Lock: ${err.name} - ${err.message}`);
    }
};

// 调用函数请求唤醒锁
requestWakeLock();

说明:该方法基于 Promise,可以在异步函数中调用,并捕获异常。


3. 释放唤醒锁

如果不再需要保持屏幕常亮,可以手动释放唤醒锁:

if (wakeLock) {
    wakeLock.release().then(() => {
        wakeLock = null;
        console.log('Wake Lock 已释放');
    });
}

释放后,设备将恢复正常的屏幕睡眠策略。


4. 侦听唤醒锁释放事件

当唤醒锁因任何原因(如用户切换标签页、浏览器最小化)被释放时,会触发 release 事件,我们可以监听它来进行处理:

if (wakeLock) {
    wakeLock.addEventListener('release', () => {
        console.log('Wake Lock 被释放');
    });
}

5. 自动重新获取唤醒锁

由于唤醒锁只在活动标签页生效,当页面可见性改变时,我们可以重新请求唤醒锁,保证用户体验连续:

document.addEventListener('visibilitychange', async () => {
    if (wakeLock !== null && document.visibilityState === 'visible') {
        await requestWakeLock();
        console.log('页面重新可见,Wake Lock 已重新获取');
    }
});

这样即便用户切换应用或锁屏,再返回页面时,屏幕仍能保持唤醒状态。


6. 完整示例

let wakeLock = null;

const canWakeLock = () => 'wakeLock' in navigator;

const requestWakeLock = async () => {
    if (!canWakeLock()) return console.warn('浏览器不支持 Wake Lock API');

    try {
        wakeLock = await navigator.wakeLock.request('screen');
        console.log('Wake Lock 已激活!');

        wakeLock.addEventListener('release', () => {
            console.log('Wake Lock 被释放');
        });
    } catch (err) {
        console.error(`获取 Wake Lock 失败: ${err.name} - ${err.message}`);
    }
};

// 页面加载或用户操作时请求唤醒锁
document.getElementById('startButton').addEventListener('click', requestWakeLock);

// 页面可见性改变时重新请求唤醒锁
document.addEventListener('visibilitychange', async () => {
    if (wakeLock !== null && document.visibilityState === 'visible') {
        await requestWakeLock();
    }
});

HTML 配套:

<button id="startButton">保持屏幕常亮</button>

7. 总结

  • Wake Lock API 是官方提供的屏幕常亮方案,比 NoSleep.js 更加高效、轻量。
  • 仅适用于活动标签页/窗口,后台标签页无法保持唤醒状态。
  • 可以通过 release 事件和 visibilitychange 自动处理锁释放和重新获取。
  • iOS Safari 尚未支持,需要 polyfill 或备用方案。

通过合理使用 Wake Lock API,H5 应用可以在视频播放、计步器、游戏等场景下提供更加流畅和持续的用户体验。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>移动端保持屏幕常亮 Demo</title>
<style>
  body {
    font-family: "Microsoft YaHei", sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    background: #f0f4f8;
  }

  button {
    padding: 12px 24px;
    font-size: 16px;
    border: none;
    border-radius: 6px;
    background-color: #007aff;
    color: #fff;
    cursor: pointer;
    margin-bottom: 20px;
  }

  button:disabled {
    background-color: #999;
    cursor: not-allowed;
  }

  #status {
    font-size: 18px;
    color: #333;
  }
</style>
</head>
<body>

<h2>移动端保持屏幕常亮 Demo</h2>
<button id="wakeButton">开启屏幕常亮</button>
<div id="status">状态:未激活</div>

<!-- iOS polyfill 引入 NoSleep.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/nosleep/0.12.0/NoSleep.min.js"></script>

<script>
  const statusEl = document.getElementById('status');
  const wakeButton = document.getElementById('wakeButton');

  let wakeLock = null;
  const noSleep = new NoSleep();

  // 检测是否支持 Wake Lock API
  const canWakeLock = () => 'wakeLock' in navigator;

  // 请求唤醒锁
  const requestWakeLock = async () => {
    if (canWakeLock()) {
      try {
        wakeLock = await navigator.wakeLock.request('screen');
        statusEl.textContent = '状态:Wake Lock 已激活';
        console.log('Wake Lock 已激活!');

        wakeLock.addEventListener('release', () => {
          statusEl.textContent = '状态:Wake Lock 被释放';
          console.log('Wake Lock 被释放');
        });

      } catch (err) {
        statusEl.textContent = `状态:获取 Wake Lock 失败 (${err.name})`;
        console.error(err);
      }
    } else {
      // iOS 不支持 Wake Lock API,使用 NoSleep.js
      noSleep.enable();
      statusEl.textContent = '状态:NoSleep 已激活 (iOS Polyfill)';
      console.log('NoSleep 已激活');
    }
  };

  // 页面可见性改变时,重新请求唤醒锁
  document.addEventListener('visibilitychange', async () => {
    if (document.visibilityState === 'visible') {
      if (wakeLock) await requestWakeLock();
    }
  });

  wakeButton.addEventListener('click', requestWakeLock);
</script>

</body>
</html>

推荐文章

38个实用的JavaScript技巧
2024-11-19 07:42:44 +0800 CST
聚合支付管理系统
2025-07-23 13:33:30 +0800 CST
25个实用的JavaScript单行代码片段
2024-11-18 04:59:49 +0800 CST
vue打包后如何进行调试错误
2024-11-17 18:20:37 +0800 CST
一个数字时钟的HTML
2024-11-19 07:46:53 +0800 CST
如何在Vue3中定义一个组件?
2024-11-17 04:15:09 +0800 CST
在 Docker 中部署 Vue 开发环境
2024-11-18 15:04:41 +0800 CST
JavaScript中设置器和获取器
2024-11-17 19:54:27 +0800 CST
如何将TypeScript与Vue3结合使用
2024-11-19 01:47:20 +0800 CST
Boost.Asio: 一个美轮美奂的C++库
2024-11-18 23:09:42 +0800 CST
Gin 框架的中间件 代码压缩
2024-11-19 08:23:48 +0800 CST
Elasticsearch 监控和警报
2024-11-19 10:02:29 +0800 CST
Linux 常用进程命令介绍
2024-11-19 05:06:44 +0800 CST
PHP设计模式:单例模式
2024-11-18 18:31:43 +0800 CST
Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
JavaScript设计模式:组合模式
2024-11-18 11:14:46 +0800 CST
Vue3中的事件处理方式有何变化?
2024-11-17 17:10:29 +0800 CST
程序员茄子在线接单