js 倒计时

倒计时是前端经常要处理的

一般有两种情况:

  1、秒杀类型,后端根据服务器时间给出当前距离秒杀点的毫秒数(这么处理防止客户端和服务器的时间不一致)

        倒计时:00411妙

  2、客户端距离一个时间点(比如距离世界杯还有多久之类的)

先搞第一种:有时一个集合页上有多个到时间,几十个.. ;于是考虑到性能和后续操作 oop组件化自然优势明显(react 也是把每个功能 组件化。思想一样)

好先上代码:1、秒杀类型

<!DOCTYPE html>
<html>
<head>
  <title>同步倒计时</title>
  <meta charset="utf-8"/>
</head>
<body>
    <span id="timebox1">11:21:55</span>
    <ul id="ul1"></ul>
    
    
    <script type="text/javascript">
        //TimeNew(id*,倒计时毫秒*,倒计时结束回调)
        function TimeNew(id,timedata,endfn){
            this.id=id;
            this.obj=document.getElementById(this.id);
            this.timedata=Math.floor(timedata/1000);
            this.endfn=endfn||undefined;
            this.tdate={};//天t,时s,分f,秒m
            this.tval;        //定时器
            this.init();
        };
        TimeNew.prototype.init=function(){
            this.timeTrade()
            this.obj.innerHTML='<em>'+this.tdate.t+'</em>天<em>'+this.tdate.s+'</em>时<em>'+this.tdate.f+'</em>分<em>'+this.tdate.m+'妙</em>';
            return this;
        };
        TimeNew.prototype.setIntervalFn=function(){
            var _this=this;
            clearInterval(this.tval);
            this.tval=setInterval(function(){
                _this.timeDataFn();
            }, 1000);
            return this;
        };
        TimeNew.prototype.timeDataFn=function() {
        if (this.timedata <= 0) {
            if(this.endfn){this.endfn()};
                clearInterval(this.tval);
        } else {
            this.timedata--;
                this.timeTrade();
                this.obj.innerHTML='<em>'+this.tdate.t+'</em>天<em>'+this.tdate.s+'</em>时<em>'+this.tdate.f+'</em>分<em>'+this.tdate.m+'妙</em>';
        };
      };
        TimeNew.prototype.timeTrade=function(){
            this.tdate.t=Math.floor(this.timedata/86400);
            this.tdate.s=Math.floor(this.timedata%86400/3600);
            this.tdate.f=Math.floor(this.timedata%86400%3600/60);
            this.tdate.m=Math.floor(this.timedata%60);
            return this;
        };
        



        //试用方法 ========================================
        new TimeNew('timebox1',15152,function(){this.obj.innerHTML=this.id+':倒计时结束了!然后我改变了他的innerHTML'}).setIntervalFn();
        
        //动态添加
        var c=[
            {
                title:'倒计时1:',
                time:262121
            },
            {
                title:'倒计时2:',
                time:8655
            },
            {
                title:'倒计时3:',
                time:89898
            },
            {
                title:'倒计时4:',
                time:25660
            }
        ];
        var oul=document.getElementById('ul1');
        for (var i=0;i<c.length; i++) {
            var d='<li>'+c[i].title+'<span id=d'+c[i].time+'></span></li>';
            oul.innerHTML+=d;
        };
        //声明多个用循环 
        for (var i=0;i<c.length; i++) {
            new TimeNew('d'+c[i].time,c[i].time,timeCallback).setIntervalFn();
        };
        
        function timeCallback(){
            console.log(this.id+':倒计时结束了!')
        };
    </script>
    
</body>
</html>

2、客户端距离一个时间点(比如距离世界杯还有多久之类的)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        距2018年世界杯:<p id="date_box_t"></p>


        <script type="text/javascript">
            /*new TimeFuture({
                nextTime:"Jun 14, 2018 0:0:01", 距离时间*
                setIntervalData:1000, 倒计时刷新频率,不填不刷新
                timeOverFn:function(o){//倒计时结束回调,  o === this
                    console.log(o.tdate)
                },
                timeFn:function(o){    //倒计时回调
                    console.log(o.tdate)
                }
            })*/
               function TimeFuture(obj){
                   if(!obj.id  && !obj.nextTime ){
                       return false;
                       console.log('必填项 id 或 nextTime 没有填写')
                   };
                   this.data={
                    nextTime:obj.nextTime,        //"Jun 23, 2017 00:00:01"
                    setIntervalData:obj.setIntervalData || false,    //不小于1000(1秒)
                    timeOverFn:obj.timeOverFn || function(o){},
                    timeFn:obj.timeFn || function(o){}
                   };
                   this.tdate={};
                this.futureT=new Date(this.data.nextTime).getTime();
                this.init();
            };
               TimeFuture.prototype.init=function(){
                this.timeTrade();
                this.data.timeFn(this);
                var _this=this;
                if(this.data.setIntervalData){
                       clearInterval(this.ntimego)
                       this.ntimego=setInterval(function(){
                           if(_this.minusT<_this.data.setIntervalData){
                               this.data.timeOverFn(_this)
                               clearInterval(_this.ntimego);
                           };
                           _this.timeTrade();
                           _this.data.timeFn(_this);
                       },this.data.setIntervalData);
                };
            }
               TimeFuture.prototype.timeTrade=function(){
                   this.minusT=(this.futureT - new Date().getTime())/1000;
                   if(this.minusT < 1){
                       this.tdate.t=this.tdate.s=this.tdate.f=this.tdate.m=0;
                   }else{
                    this.tdate.t=Math.floor(this.minusT/86400);
                    this.tdate.s=Math.floor(this.minusT%86400/3600);
                    this.tdate.f=Math.floor(this.minusT%86400%3600/60);
                    this.tdate.m=Math.floor(this.minusT%60);
                   };
                return this;
            };

               
               //倒计时 应用 ==================
               var odatebox=document.getElementById('date_box_t');
            var tf= new TimeFuture({
                id:'date_box_t',
                nextTime:"Jun 14, 2018 0:0:01",
                setIntervalData:1000,
                timeOverFn:function(o){
                    console.log('倒计时结束')
                    console.log(o.tdate)
                },
                timeFn:function(o){
                    console.log(o.tdate)
                    odatebox.innerHTML=o.tdate.t+""+o.tdate.s+""+o.tdate.f+""+o.tdate.m+"";
                }
            })

        </script>
    </body>
</html>

  两个传参形式不同后面会统一完善, 请持续关注

原文地址:https://www.cnblogs.com/SongYiJian/p/5583502.html