JS30 day29 - Countdown Timer
作業內容
今天的作業是做出一個倒數的頁面,有按鈕可按,也可以自訂要倒數幾分鐘
雖然聽起來頗為簡單,但做起來要超多細節要注意
可以看這份 codepen
學到什麼
-
JS
直覺想到倒數的功能是使用 setInterval
可是這會有幾個比較不友好的點:比方說在 ios 上面 scroll 的時候他自動會把這功能停掉,你滾動 10 秒的話倒數就少了 10 秒,所以建議不要在這邊用 setInterval1
2
3
4
5function timer(seconds){
setInterval(function(){
seconds--;
}, 1000)
}- 讓 setInterval 在倒數完之後不繼續運作
最直覺想到的可能會是這樣:
1
2
3
4
5setInterval(function(){
const secondsLeft = Math.round((then - Date.now()) / 1000)
if(secondsLeft < 0) return;
console.log(secondsLeft)
}, 1000)但 return 不能真正解決問題,他只是不繼續往下執行,每秒還是會觸發這個事件,所以要用 cleanInterval
我們要在他自己的方法裡面停掉自己,所以先做出一個 global 的 coundown 變數再用 clearInterval 停掉它1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16let countdown
function timer(seconds){
// const now = (new Date()).getTime()
// 上面這種寫法也可以
const now = Date.now() // mili seconds 的形式
const then = now + seconds * 1000
countdown = setInterval(function(){
const secondsLeft = Math.round((then - Date.now()) / 1000)
if(secondsLeft < 0) {
clearInterval(countdown)
return
}
console.log(secondsLeft)
}, 1000)
}- 有個很細節的地方:目前我們呼叫 timer 的時候,他當下不會觸發時間,而是過一秒之後才開始,可以看下圖,想要的效果是如果呼叫
timer(10)
當下會先說出 10
因此我們要改成這樣
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function timer(seconds){
// const now = (new Date()).getTime()
// 上面這種寫法也可以
const now = Date.now() // mili seconds 的形式
const then = now + seconds * 1000
displayTimeLeft(seconds)
countdown = setInterval(function(){
const secondsLeft = Math.round((then - Date.now()) / 1000)
if(secondsLeft < 0) {
clearInterval(countdown)
return
}
displayTimeLeft(secondsLeft)
}, 1000)
}
function displayTimeLeft(seconds){
console.log(seconds)
}- 如果在按下一個 timer 又按另一個 timer 之後,這些 setInterval 的效果會疊加,所以在開始另一個之前要先把先前的停掉
1
2
3
4function timer(seconds){
// 開始另一個 timer 之前先把之前的 setInterval 停掉
clearInterval(countdown)
// 下略- 我們可以直接用
document.<form 的 name>
這個方式來呼叫 form,可以再用一層呼叫 input 的 name
1
2
3<form name="customForm" id="custom">
<input type="text" name="minutes" placeholder="Enter Minutes">
</form>1
2
3
4document.customForm
// <form name="customForm" id="custom">
document.customForm.minutes
// <input type="text" name="minutes" placeholder="Enter Minutes"> - 讓 setInterval 在倒數完之後不繼續運作
https://github.com/wesbos/JavaScript30
code 內容:
HTML:
1 | <div class="timer"> |
CSS:
1 | html { |
JS:
1 | let countdown |