純js實現(xiàn)倒計時功能
通過js實現(xiàn)頁面的倒計時功能。
思路: 傳入一個秒數c,c/60可以得到分鐘m, c%60可以得到顯示的秒數s,同理,再將m/60可是得到小時數, m/%可以得到分鐘數。通過setInterval每次將總秒數-1,并將計算所得時間顯示到頁面上。
第一版的骯臟代碼如下, 可以作為反面教材思考一下
<html>
<head>
<title>Tomato</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
var vTimeLength = 5;
var vHour;
var vMinutes;
var vSeconds;
var vRemainingTime;
function countDown(){
vTimeLength = vTimeLength - 1;
vMinutes = Math.floor(vTimeLength/60);
vSeconds = Math.floor(vTimeLength%60);
if (vMinutes >= 60){
vHour = Math.floor(vMinutes/60);
var vMinutesNew = Math.floor(vMinutes%60);
vRemainingTime = vHour + ":" + vMinutesNew + ":" + vSeconds;
} else {
vRemainingTime = vMinutes + ":" + vSeconds;
}
document.getElementById("div_countDown").innerHTML = vRemainingTime;
if (vTimeLength < 1) {
alert('do sth');
}
}
</script>
</head>
<body>
<div id="div_countDown"></div>
<script type="text/javascript">
setInterval("countDown()", 1000);
</script>
</body>
</html>
缺陷:
1、定義了眾多的全局變量,
2、沒有復用性,
3、setInterval容易導致隊列過多, 結束事件如果是非阻塞事件, 倒計時會繼續(xù)執(zhí)行出現(xiàn)負數,
4、不符合面向對象思想。。。
針對缺陷1的解決方案是, 定義一個函數, 將相關全局變量放到函數內部,使之成為局部變量
針對缺陷2:為函數指定參數,提高復用性。 這里定義了3個參數vTimeLength為倒計時總秒數,showTagId為顯示到頁面元素的id, callback為倒計時結束后的回掉方法
針對缺陷3:用setTimeout替代setInterval
優(yōu)化后的代碼如下:
<html>
<head>
<title>countdown</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function countDown(vTimeLength, showTagId, callback) {
var vHour;
var vMinutes;
var vMinutesNew
var vSeconds;
var vRemainingTime;
function countDownInner(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>
<div id="div_countDown"></div>
<script type="text/javascript">
countDown(5, "div_countDown", function(){alert('do sth');});
</script>
</body>
</html>
這里有一點需要注意
setTimeout(function(){countDownInner(vTimeLength);}, 1000);
第一次我將此句寫成了
setTimeout(countDownInner(vTimeLength), 1000);
結果函數直接執(zhí)行了, 沒有等待1秒的時間。如果沒有入參, 即setTimeout("countDownInner()", 1000); 則可正常執(zhí)行。
至于前面提到的不夠面向對象的缺陷, 也是剛剛接觸, 這里貼出代碼,希望能夠互相交流
<html>
<head>
<title>count_down</title>
<script type="text/javascript">
var countDown = {
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;
}
var that=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);
} else if (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);
}
};
function countDownStart() {
countDown.run();
}
function countDownStop() {
countDown.stop();
}
</script>
</head>
<body>
<div id="div_countDown"></div>
<script type="text/javascript">
countDown.run(5, 'div_countDown',function(){alert('12')});
</script>
<span>
<button onclick="countDownStart();">start</button>
<button onclick="countDownStop();">stop</button>
</span>
</body>
</html>
一個難點是this的使用, 在函數內部, this是調用當前函數范圍,所以setTimeout(function(){this.countDownInner(vTimeLength);}, 1000);會出現(xiàn)undefined。
解決方案是定義一個that變量接收外部函數的this指針,然后通過that即可調用外部域。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關文章
不用AI也能實現(xiàn)的文字自動播報(SpeechSynthesis文本實例合成)
SpeechSynthesis是HTML5的一個新特性,基于SpeechSynthesis可以實現(xiàn)在客戶瀏覽器端進行動態(tài)文本的語音合成播放,這篇文章主要介紹了不用AI也能實現(xiàn)的文字自動播報(SpeechSynthesis文本實例合成),需要的朋友可以參考下2023-03-03

