H5 - - - - - 移动端息屏后setInterval定时器不工作的问题

移动端息屏后setInterval定时器不工作的问题

  • 1. 场景描述 & 问题描述
  • 2. 解决思路
    • 2.1 方案一
    • 2.2 方案二
  • 3. 实现代码

1. 场景描述 & 问题描述

场景描述:

进入页面通过接口获取一个当前倒计时时间戳,然后前端通过setInterval定时器轮询-1进行倒计时展示

问题描述:

当倒计时开启,经过一段时间接近目标时间时,多人反馈剩余倒计时时间不统一。经过一番定位猜测以及尝试之后,发现问题出现在setInterval定时器上。
不管是Android还是iOS都存在息屏后,过了一段时间后定时器会停止工作,再次打开后才继续工作的问题,且息屏后多长时间定时器会停止工作不确定。

2. 解决思路

能否通过监听页面是否可见来进行倒计时时间订正?

2.1 方案一

  • 通过监听 visibilitychange 事件,得知该页面是否为可见。
  • 在息屏时,我们主动关闭定时器,并记录当前时间。
  • 在用户打开手机进入页面时,记录当前时间,计算出息屏期间的时间。
  • 再次打开定时器,订正计时器时间加上息屏期间的时间。

2.2 方案二

  • 通过监听 visibilitychange 事件,得知该页面是否为可见。
  • 当解锁时重新获取倒计时时间

当前示例为方案一实现。⬇️

3. 实现代码

<template>
  <div>
    <div>剩余时间:{{ countdown }}div>
    <div>是否为熄屏状态:{{ screenShutdownStatus }}div>
    <div>上次熄屏的时间戳:{{ screenShutdownTime }}div>
    <div>当前解锁的时间戳:{{ unlockTime }}div>
  div>
template>
<script>
import moment from "dayjs";
export default {
  name: "Home",
  data() {
    return {
      timer: null, // 定时器
      countdown: 10000, // 倒计时时间
      screenShutdownStatus: false, // 手机是否为熄屏状态
      screenShutdownTime: null, // 熄屏的时间戳
      unlockTime: null, // 解锁时间
    };
  },
  mounted() {
    // 启用定时器
    this.auto();

    // 监听页面是否可见
    document.addEventListener("visibilitychange", this.watchVisibility);
  },
  methods: {
    /**
     * 添加定时器:定时器轮询-1
     */
    auto() {
      const _this = this;
      this.timer = setInterval(() => {
        --_this.countdown;
      }, 1 * 1000);
    },

    /**
     * 销毁定时器
     */
    clearIntervalTimer() {
      this.timer = null;
      clearInterval(this.timer);
    },

    /**
     * 监听页面是否可见
     */
    watchVisibility() {
      // 页面不可见(即手机熄屏状态)
      if (document.visibilityState == "hidden") {
        /**
         * 手机变为熄屏状态
         * 1. 标识为熄屏状态
         * 2. 记录当前时间戳
         * 3. 清除定时器
         */
        this.screenShutdownStatus = true;

        this.screenShutdownTime = Date.now();

        this.clearIntervalTimer();
      } else {
        // 页面可见(即手机解锁)
        /**   页面变为可见状态
         * 1. 标识为解锁状态
         * 2. 获取当前时间与熄屏时间计算时间差,订正倒计时时间
         * 3. 重新开启倒计时
         */
        this.screenShutdownStatus = false;

        let time = Date.now();
        this.unlockTime = time;
        let diffTime = time - this.screenShutdownTime;
        this.countdown -= diffTime;

        this.auto();
      }
    },
  },

  /**
   * 页面卸载,销毁定时器
   */
  destroyed() {
    this.clearIntervalTimer();
  },
};
script>

你可能感兴趣的:(移动端,H5移动端)