纯js实现倒计时功能
通过js实现页面的倒计时功能。
思路:传入一个秒数c,c/60可以得到分钟m,c%60可以得到显示的秒数s,同理,再将m/60可是得到小时数,m/%可以得到分钟数。通过setInterval每次将总秒数-1,并将计算所得时间显示到页面上。
第一版的肮脏代码如下,可以作为反面教材思考一下
<html> <head> <title>Tomato</title> <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/> <scripttype="text/javascript"> varvTimeLength=5; varvHour; varvMinutes; varvSeconds; varvRemainingTime; functioncountDown(){ vTimeLength=vTimeLength-1; vMinutes=Math.floor(vTimeLength/60); vSeconds=Math.floor(vTimeLength%60); if(vMinutes>=60){ vHour=Math.floor(vMinutes/60); varvMinutesNew=Math.floor(vMinutes%60); vRemainingTime=vHour+":"+vMinutesNew+":"+vSeconds; }else{ vRemainingTime=vMinutes+":"+vSeconds; } document.getElementById("div_countDown").innerHTML=vRemainingTime; if(vTimeLength<1){ alert('dosth'); } } </script> </head> <body> <divid="div_countDown"></div> <scripttype="text/javascript"> setInterval("countDown()",1000); </script> </body> </html>
缺陷:
1、定义了众多的全局变量,
2、没有复用性,
3、setInterval容易导致队列过多,结束事件如果是非阻塞事件,倒计时会继续执行出现负数,
4、不符合面向对象思想。。。
针对缺陷1的解决方案是,定义一个函数,将相关全局变量放到函数内部,使之成为局部变量
针对缺陷2:为函数指定参数,提高复用性。这里定义了3个参数vTimeLength为倒计时总秒数,showTagId为显示到页面元素的id,callback为倒计时结束后的回掉方法
针对缺陷3:用setTimeout替代setInterval
优化后的代码如下:
<html> <head> <title>countdown</title> <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/> <scripttype="text/javascript"> functioncountDown(vTimeLength,showTagId,callback){ varvHour; varvMinutes; varvMinutesNew varvSeconds; varvRemainingTime; functioncountDownInner(vTimeLength){ vMinutes=Math.floor(vTimeLength/60); vSeconds=Math.floor(vTimeLength%60); if(vMinutes>=60){ vHour=Math.floor(vMinutes/60); vMinutesNew=Math.floor(vMinutes%60); vRemainingTime=vHour+":"+vMinutesNew+":"+vSeconds; }else{ vRemainingTime=vMinutes+":"+vSeconds; } document.getElementById(showTagId).innerHTML=vRemainingTime; vTimeLength=vTimeLength-1; if(vTimeLength>0){ setTimeout(function(){countDownInner(vTimeLength);},1000); }else{ callback(); } } countDownInner(vTimeLength); } </script> </head> <body> <divid="div_countDown"></div> <scripttype="text/javascript"> countDown(5,"div_countDown",function(){alert('dosth');}); </script> </body> </html>
这里有一点需要注意
setTimeout(function(){countDownInner(vTimeLength);},1000);
第一次我将此句写成了
setTimeout(countDownInner(vTimeLength),1000);
结果函数直接执行了,没有等待1秒的时间。如果没有入参,即setTimeout("countDownInner()",1000);则可正常执行。
至于前面提到的不够面向对象的缺陷,也是刚刚接触,这里贴出代码,希望能够互相交流
<html> <head> <title>count_down</title> <scripttype="text/javascript"> varcountDown={ flag:true, hour:0, minutes:0, minutesNew:0, seconds:0, show:0, current:0, length:0, showTagId:null, //callback:null, countDownInner:function(vTimeLength){ if(!this.flag){ return; } varthat=this; this.current=vTimeLength; minutes=Math.floor(vTimeLength/60); seconds=Math.floor(vTimeLength%60); if(minutes>=60){ hour=Math.floor(minutes/60); minutesNew=Math.floor(minutes%60); show=hour+":"+minutesNew+":"+seconds; }else{ show=minutes+":"+seconds; } document.getElementById(this.showTagId).innerHTML=show; vTimeLength=vTimeLength-1; if(vTimeLength>0){ setTimeout(function(){that.countDownInner(vTimeLength);},1000); }else{ setTimeout(function(){that.callback();},1000); } }, run:function(vTimeLength,showTagId,callback){ if(!this.flag){ this.flag=true; this.countDownInner(this.current); }elseif(showTagId){ this.length=vTimeLength; this.showTagId=showTagId; this.callback=callback; this.countDownInner(vTimeLength); } }, stop:function(){ this.flag=false; }, restart:function(){ this.flag=true; this.countDownInner(this.length); } }; functioncountDownStart(){ countDown.run(); } functioncountDownStop(){ countDown.stop(); } </script> </head> <body> <divid="div_countDown"></div> <scripttype="text/javascript"> countDown.run(5,'div_countDown',function(){alert('12')}); </script> <span> <buttononclick="countDownStart();">start</button> <buttononclick="countDownStop();">stop</button> </span> </body> </html>
一个难点是this的使用,在函数内部,this是调用当前函数范围,所以setTimeout(function(){this.countDownInner(vTimeLength);},1000);会出现undefined。
解决方案是定义一个that变量接收外部函数的this指针,然后通过that即可调用外部域。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!