在手机版网页中做倒计时(使用服务端时间来倒计时)我们需要考虑到两个问题: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中instant
与servertime
是同时定义可以减少误差):
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的执行暂停,纯属猜测),这时我们需要对倒计时进行校正,对于这个问题我也有两种解决方法:
- 使用定时器隔一段时间自动校正一次;
- 使用
visibilitychange
事件来监听document
的隐藏状态,即查看document.hidden
值,false
为页面显示,true
为页面隐藏:
第一种方法随可行但有一定的弊端,建议使用第二种方法。document.addEventListener("visibilitychange", function (e) { if(!e.path[0].hidden){ // e.path为页面中document的集合 // 校正倒计时的代码... } }, false);
至此,手机版网页js倒计时的两个问题得到了解决。
其他参考博客:
vue实现倒计时的插件 时间戳 刷新 跳转 都不影响
vue实现倒计时的插件 时间戳 刷新 跳转 都不影响 - 实现丰盛 - 博客园