最近朋友问我关于倒计时的问题,我就想起来我以前写过的红包雨项目,在某一天某一点开始下红包雨,当时倒计时写的很顺利。现在细思,确实是有问题的。具体的问题,是值得记录的,供大家参考,不要走我的老路。
作为前端小白时,我们书写,倒计时是基本功,当时用的 new.Date() ,获取本地时间作为时间参考,写的没有问题。但是实际项目中,不应该使用只是用 new.Date() , 因为它获取的是电脑系统本地时间,这个时间是可以修改的,我测试过,比如设置的倒计时是到第二天凌晨开始下红包雨,而我在本地将系统时间修改问第二天凌晨,那么就会开始下红包雨。为了解决这个BUG。我们就需要后台传递给我们一个时间戳。利用时间戳,进行递减操作解决这个BUG。
//假设请求获取的两个时间戳 StartTime EndTime
var TimeDiff = EndTime - StartTime;
var timer = setInterval(function(){
TimeDiff--;
//执行页面倒计时渲染的code
},0)
这两天和同事又在讨论,关于倒计时的问题,从服务器获取时间戳是没问题的,但是网络的延迟就会影响到倒计时的准确性。就此问题,我又查找了不下50篇文档。终于,究极进化版诞生。
//从服务器获取截止时间 ---> EndTime
//开始倒计时的起始时间,我们应该获取的是服务器返回数据的时间,这个就不能又服务器传值了,这样网络延迟就会影响准确性。
var i = 0;
var timer;
getfwqtime();
function getfwqtime(){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new window.XMLHttpRequest();
}else{ // ie
xhr = new ActiveObject("Microsoft")
}
// 通过get的方式请求当前文件
xhr.open("get","");
xhr.send(null);
// 监听请求状态变化
xhr.onreadystatechange = function(){
var time = null,
curDate = null;
if(xhr.readyState===2){
time = xhr.getResponseHeader("Date");
nowtime = new Date(time).getTime();
console.log(nowtime);
//此时获取的时间正是请求成功并且结束后的服务器时间,这个是不需要服务器传输的。在服务器上的网站,我们去请求加载的时候,自行执行这个请求时间的函数,就会获取到正确的时间,也不用担心用户在本地修改导致的程序错误。
//这后面是你要执行的倒计时
if(nowtime > Endtime){
return false;
}else{
timer = setInterval('getRTime(Endtime,nowtime)',1000);
}
}
}
}
function getRTime(Endtime,nowtime){
NowTime += i;
var t = EndTime - NowTime;
var m=Math.floor(t/1000/60%60);
var s=Math.floor(t/1000%60);
if(t>0){
$('.minute').html(m);
$('.second').html(s);
i+=1000;
}else{
$('.minute').html('0');
$('.second').html('0');
clearInterval(timer)
}
}
大功告成!