实现多个倒计时(解决本地时间误差问题)

踩坑过程:业务需求实现倒计时组件,可以在后台管理系统实现装修,小程序正常展示,拿到需求后正常进行开发然后就给测试人员,结果就提了个bug:本地时间故意设置错误,导致倒计时不正确。
本地时间故意设置错误,导致倒计时不正确
当时开发的时候没有想到这么多,直接拿Date.now()来倒计时了,结果就悲剧了~

解决方法:

思路:加载时和切换显示的时候获取服务器的时间,然后和本地时间也就是Date.now()或者New Date().getTime()进行对比,然后记录时间差也就是 timeGap = serverTime - Date.now(),然后在倒计时时间处理的时候加上时间差,也就是 nowTime = Date.now() + timeGap。

1.管理后台pc端的倒计时处理

 getServerTime() {//获取服务器时间,其实和接口数据的请求头里面返回的那个时间一样
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest();
        if (!xhr) {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xhr.open("HEAD", location.href, true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                resolve(xhr.getResponseHeader("Date"));
            }
        }
        xhr.send(null);
    })
}
...
// 监听页面隐藏和显示事件,避免第一次获取服务器时间后,中途修改了本地时间
document.addEventListener("visibilitychange", async function() {//注意兼容性
  if (document.hidden) { //页面被切到后台-隐藏
        clearInterval(Intervals);
    } else { //页面被切到前台-显示
        let serverTime = await getServerTime();        
        //倒计时只精确到秒
        var timeGap = parseInt((new Date(serverTime).getTime() - Date.now()) / 1000);
    }
});
...
//可以愉快地开始倒计时咯
 var Intervals= setInterval(async () => {
     let nowTime = parseInt(Date.now() / 1000) + that.countdown_timeGap; //当前时间
      for (let i in data) {
            //状态判断:未开始1,未结束2,已结束
            ...           
      }
}, 1000);

2.微信小程序端的倒计时处理

//在app.js的onshow事件里有个请求,用这个请求接口返回的请求头的时间来刷新我们的服务器时间
 onShow: function (e) {
  wx.request({
      url: url,
      method: method,
      data: data,
      header: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      success: function (res) {
	  		//记录服务器时间差
      		this.serverTimeGap = parseInt(new Date(res.header.Date).getTime() - Date.now()) / 1000;
      }
    });
 }
 //可以愉快地开始倒计时咯
 var Intervals= setInterval(async () => {
     let nowTime = parseInt(Date.now() / 1000) + getApp().serverTimeGap; //当前时间
      for (let i in data) {
            //状态判断:未开始1,未结束2,已结束
            ...           
      }
}, 1000);

OK,以上~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值