小虾虎鱼

小虾虎鱼

手机版网页js倒计时存在的问题与解决的方法

作者 禾惠 发表于 2015/04/10,最后修改于 2015/04/10

在手机版网页中做倒计时(使用服务端时间来倒计时)我们需要考虑到两个问题:1、避免频繁的取服务端时间2、手机处于锁屏状态或者浏览器/页面在后台运行对倒计时的处理;围绕这两个问题说说我的解决方法(小 虾虎 鱼原创)。

一、服务端时间的获取方法

实现倒计时功能,我们必须要知道剩余时间,知道剩余时间就必须要知道当前时间(服务器时间)和结束时间。 服务器时间和结束时间可以通过两种方式获得:

  1. 后端直接在视图中输出;
  2. 通过ajax去获取;

为了减少http请求我选择第一种方式,将结束时间和服务端时间直接在视图中输出,如:

<head>
    <script>
        var servertime = '2015-4-10 09:32:17'; 
        var endtime = '2015-4-12 09:00:00';
    </script>
</head>

得到两个时间之后,结束时间endtime是一直不变的,但服务器时间servertime是一直在变的,而我们只得到了一次服务器时间,这时我们需要实现如何与服务器时间同步,我们可以这样做: 在页面打开时我同时记录这一刻的时间,并将这时间保存到一个变量instant中,然后在页面打开后的任一时间想得到服务端的时间可以通过当前本地的时间减去instant的时间再加上servertime时间,即:Date.now() - instant + servertime,我们将下面的js代码放到html页面中的head中(放到head中instantservertime是同时定义可以减少误差):

        var servertime = '2015-4-10 09:32:17'; 
        var endtime = '2015-4-12 09:00:00';
        var instant = Date.now();

最后我们通过Date.now() - instant + servertime计算时间差来实现倒计时。

【注意】使用此方法会存在以下问题:

  • 如果客户端的时间被修改,那么得到的服务端时间就不正确;
  • 如果网络环境差也会造成一定的误差;

二、设备锁屏或浏览器/页面后台运行的影响

如果设备处于锁屏或者浏览器/页面处于后台运行状态过一段时间再返回到页面,会发现倒计时慢了(具体原因我不知道,有可能浏览器处于休眠状态导致JS的执行暂停,纯属猜测),这时我们需要对倒计时进行校正,对于这个问题我也有两种解决方法:

  1. 使用定时器隔一段时间自动校正一次;
  2. 使用visibilitychange事件来监听document的隐藏状态,即查看document.hidden值,false为页面显示,true为页面隐藏:
    document.addEventListener("visibilitychange", function (e) {
         if(!e.path[0].hidden){ // e.path为页面中document的集合
             // 校正倒计时的代码...
         } 
    }, false);
    
    第一种方法随可行但有一定的弊端,建议使用第二种方法。

至此,手机版网页js倒计时的两个问题得到了解决。