今天开需求评审会,看原型文档里面有一板块是一个天:时:分:秒
的倒计时。开完会,去项目的模块里看了看,WTF,居然没有倒计时的模块,那只有自己写一个了。
首先,后台返回的是以毫秒为单位的时间,那来看思路=>
假如,现在有一时间段是1234567899ms。
换算一下:1234567899ms == 1234567.899s
。这里我们可以把0.899s
省去,先保留整数来换算,稍后再来处理0.899s
。
以下是换算过程:
1234567/60 => 20576分+7秒
20576/60 => 342小时+56分
342/24 => 14天 + 6小时
经过以上换算过程,根据倒计时格式,对应的就是14天:6小时:56分:7秒
,在这个基础上,一秒一秒的往下走,也就是1234567依次--,直到0;
返回来说剩余的0.899s
,受到iphone上秒表的启发,毫秒部分的倒计时是以两位来进行的,如下图:
毫秒位是从0到99,也就是每1毫秒加1,直到增加到99,然后进位,秒数加1,所以按照这个原理,我们可以把多余的
0.899s
保留两位小数,也就是0.899.toFixed(2) => 0.90
,这里换算出来的就是四舍五入以后的值,然后取小数点后的值,也就是90。在倒计时进行前,先把
0.90s
消耗完,也就是以每1毫秒减1的速度从90减到0,然后再运行倒计时。所以,在这个思路中,有两个倒计时,一个是消耗0.90s
的倒计时,一个是咱们需要展示在页面上的倒计时。
以下是全部代码。
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id='countDown'></div>
</body>
<script>
function TimeDown(ele,opt,cb){
ele = ele.indexOf('#') == 0?document.getElementById(ele.replace('#','')):(ele.indexOf('.') == 0?document.getElementsByClassName(ele.replace('.',''))[0]:console.error('ele is classname or id'))
var tt = this;
var TD = {
dealToPend:function(s,ele){
var sa = s.split(':');
var sal = sa.length;
var st = '';
for(var i=0;i<sal;i++){
sa[i] = sa[i].toString().length == 1?'0'+sa[i]:sa[i];
st+=sa[i]+':';
}
ele.innerHTML = st.substring(0,st.length-1);
},
dd:function(int){
var dd = Math.floor(Math.floor(Math.floor(int/60)/60)/24);
var hh = Math.floor(Math.floor(int/60)/60)%24;
var mm = Math.floor(int/60)%60;
var ss = int%60;
return dd+':'+hh+':'+mm+':'+ss;
},
hh:function(int){
var hh = Math.floor(int/60/60);
var mm = Math.floor(int/60)%60;
var ss = int%60;
return hh+':'+mm+':'+ss;
},
mm:function(int){
var mm = Math.floor(int/60);
var ss = int%60;
return mm+':'+ss;
}
}
tt.time = Math.floor(tt/1000);
tt.f = '';
tt.dealInt = function(int){
var tdt = setInterval(function(){
if(int == 1){
clearInterval(tdt);
if(cb){
cb();
}
return;
}
int--;
TD.dealToPend(TD[opt](int),ele);
},1000)
}
tt.dealFloat = function(float,int){
var fdt = setInterval(function(){
if(float == 0){
clearInterval(fdt);
tt.dealInt(int);
}
float--;
},1)
}
tt.dealFloatms = function(){
tt.f = (tt/1000-tt.time).toFixed(2)*100;
tt.dealFloat(tt.f,tt.time);
}
//避免page load出现短暂空白时间
TD.dealToPend(TD[opt](tt.time),ele);
//是否存在不够一秒的情况
tt%1000 != 0?tt.dealFloatms():tt.dealInt(tt.time);
}
Number.prototype.timedown = TimeDown;
var differ = new Date('2018-05-16 24:00').getTime() - new Date().getTime();
var fn = function(){
document.getElementById('countDown').innerHTML = 'time is up';
}
//第一个参数是用于盛放倒计时元素的id或者classname
//第二个参数是倒计时格式
//'dd':代表 天:小时:分:秒
//'hh':代表 小时:分:秒
//'mm':代表 分:秒
//目前只支持以上三种格式
//第三个参数是倒计时结束的回调
differ.timedown('#countDown','dd',fn);
</script>
</html>
这其中可能有不到1毫秒的误差,甚至不到0.01毫秒,因为在setInterval和setTimeout两个方法中,只有执行次数到千万甚至亿级别,才有不到1毫秒的误差,所以误差在0.01毫秒级别的可以省略。感兴趣的可以用time和timeEnd试一试。
网友评论