倒计时

2018-05-11  本文已影响25人  MrOldK

今天开需求评审会,看原型文档里面有一板块是一个天:时:分:秒的倒计时。开完会,去项目的模块里看了看,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上秒表的启发,毫秒部分的倒计时是以两位来进行的,如下图:

WechatIMG780.png
毫秒位是从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试一试。

上一篇下一篇

猜你喜欢

热点阅读