纯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即可调用外部域。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!