前端倒计时的几种实现方式

2,172 阅读1分钟

前端倒计时的几种实现方式

需求:

  • 实现一个倒计时,后台返回倒计时还剩多少秒,前端在此基础上按秒倒计;
  • 当后台数据还未返回时,倒计时区域显示 倒计时 - :- :-

  • 当后台数据 <= 0 时,倒计时区域显示 ‘倒计时 00:00:00’,并弹出一个弹框;

  • 尽量减少本机电脑时间的修改对倒计时的影响;

这里有个坑需要注意下:

一开始的想法就是通过定时器每隔 1s 倒计时减 1 来实现;结果发现用 setInterval 或 setTimeout 做倒计时,当页面不可见时,浏览器为了节省资源,会放缓定时器的执行时间;比如:设置每秒执行 1 次,当页面不可见时,可能是每 2 秒才执行一次,具体多久执行一次各个浏览器不一致;当回到本页面时,定时器恢复正常;可参考:juejin.cn/post/689979…

  • 方案一:codesandbox.io/s/react-hoo…

    • 拿到后台返回的数据 seconds 后,记录下本机的当前时间作为初始时间 initialTime;
    • 定时 1s 执行 handleCountdown 函数,在这个函数中,initialTime + seconds - now 就是剩余的秒数;now 是每次调用 handleCountdown 时本机当前时间; 尽管 handleCountdown 不一定是每秒执行一次(页面不可见时执行间隔会变长),但每次执行都是减去本机的当前时间,因此算出的剩余秒数是正确的;在倒数的过程中,修改本机时间会影响倒计时;在拿到后台返回的数据之前修改本机时间,不会影响倒计时;
  • 方案二:codesandbox.io/s/react-hoo…

    • 定时 1s 执行 handleCountdown 函数,在这个函数中,接收一个需扣掉的毫秒数 millionSeconds(默认是 1000 ms),每执行一次减去 millionSeconds;
    • 监听 visibilitychange 事件,当页面不可见时,清除定时器并且保存页面不可见时本机的当前时间;当页面可见时,计算可见时间点与不可见时间点的时间间隔 diff,调用 handleCountdown,传入 diff;
    • 注意:请求数据返回之前切出页面的话,此时没有设置定时器,等到切回来之后,计算 diff,得出倒计时; 这种方式倒计时完全不受本机时间的影响。