
今日是JavaScript計時器教學的下篇,今日我們會將上次教學的簡化版計時器內容,改成像上面這張圖片這樣,較為精緻、功能上也較多的完整計時器,如果你是還沒看過上一篇內容的朋友,連結在這裡喔!
JavaScript計時器 程式實作
接續上次我們所實作的簡化版,相信現在你對於JavaScript是如何和靜態的Html元素做互動有一個基本的概念了,基本上就是我們透過id找到特定元素之後,針對元素做值以及程式邏輯上的運用而已,非常的簡單,所以我們今天要繼續用這個概念實作出更完整的計時器,上次的計時器只達到能夠讓使用者倒數計時而已,並不能夠像是一般的計時器去輸入時、分、秒,也不能倒計數到一半就做停止或者重設,並且在顯示上也不夠直觀,所以我們今天就會將這些一項一項完成,那就開始吧!
顯示時、分、秒
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<STYLE>
<!--
input{
font-size:180px ;
width: 20%;
float:left;
text-align:center;
}
p{
font-size:180px;
float:left
}
-->
</STYLE>
</head>
<body>
<h1>JavaScript教學-計時器</h1>
<div style="margin:0px auto; width:80%;" >
<input
onkeyup="value=value.replace(/[^\d]/g,'') "
ng-pattern="/[^a-zA-Z]/"
value= 0
maxlength="2"
onblur="setHour()"
onchange = "checkNumber(value,id)"
id = "setHour";
></input>
<p>  : </p>
<input
onkeyup="value=value.replace(/[^\d]/g,'') "
ng-pattern="/[^a-zA-Z]/"
value= 0
maxlength="2"
onblur="setMinute()"
id = "setMinute";
></input>
<p> : </p>
<input
onkeyup="value=value.replace(/[^\d]/g,'') "
ng-pattern="/[^a-zA-Z]/"
value= 0
maxlength="2"
onblur="setSecond()"
id = "setSecond";
></input>
</div>
<div >
<button
style="width:15% ;height:100px;position: absolute; top:55%;left:20%;font-size: 50px;"
class="btn btn-success"
id = "start"
onclick = "startCounting()"
>開始</button>
<button
style="width:25% ;height:100px;position: absolute; top:55%;left:45%;font-size: 50px"
class="btn btn-primary"
onclick = "addMinute()"
id= "reset"
>增加一分鐘</button>
</div>
看起來很長,但其實都是在重複相同的東西而已,首先是我們對於時、分、秒,為了要讓其能夠有讓使用者輸入的效果,我們必須要使用Input欄位,並且我們為了保證使用者不會對於Input搞怪,所以我們設置了onkeyup以及ng-pattern的正規式,來避免使用者隨便輸入數字以外的東西導致程式當機,並且我們限制分和秒最大長度為2位數,避免百位數的出現,不過我寫到後面發現這樣並沒有辦法規避六十以上的數字,會有更好的方法的,此處只是告訴大家這是一個方式,接著我們必須要使用onBlur()的方法,這代表只要你Input過後將滑鼠移開,就會觸發onBlur()裡面的方法,這樣子我們就可以確保使用者輸入的內容可以馬上被接收到,這邊大致為了接下來JavaScript的內容需要先準備的HTML和CSS的部分,而在前面的部分我有使用到一點BootStrap來讓畫面變得更加好看,完全不了解BootStrap的同學只要知道我等於是引入了一個超大CSS檔案,然後去找到對應的Class套用他們的style而已,詳情大家可以參考這篇文章。
https://tw.alphacamp.co/blog/bootstrap-4-introduction
接受使用者輸入的時間
let hour = 0;
let minute = 0;
let second = 0;
function setHour(){
hour = parseInt(document.getElementById("setHour").value)
console.log(hour)
}
function setSecond(){
let setSecond = document.getElementById("setSecond")
second = parseInt(setSecond.value)
console.log(setSecond)
if(second>=60){
second = 59
//調整該項目
setSecond.value = 59
}
console.log(second)
}
function setMinute(){
let setMinute = document.getElementById("setMinute")
minute = parseInt(setMinute.value)
if(minute>=60){
minute = 59
//調整該項目
setMinute.value = 59
}
}
這邊我們只需要觀看setSecond()方法就可以明白其他兩者的運作方式了,都是大同小異的,首先一樣都是透過document.getElementById接受使用者的setMinute標籤,再來要注意的是,由於使用者輸入在input的欄位會被JavaScript默認為字串,所以我們必須要將其先用parseInt()的方法轉換為數字,而再來則是我們必須要判斷這個數字有沒有大於60,由於如果大於60就不是時間了,所以只要大於60我們一率將其設置為59,而小時和秒的設定我們只需要以此類推,這樣就完成了!
開始計時
let timer = 0;
function startCounting(){
//確保value沒跑掉
setHour = document.getElementById("setHour")
setSecond = document.getElementById("setSecond")
setMinute = document.getElementById("setMinute")
hour = parseInt(setHour.value)
second = parseInt(setSecond.value)
minute = parseInt(setMinute.value)
if(hour === 0 && second === 0 && minute === 0){
console.log("不會執行")
}else{
timer = window.setInterval("Check_Time()", 1000);
//將input field屬性做更改 不能更改 且可以改變樣式
setHour.setAttribute('disabled','disabled')
setMinute.setAttribute('disabled','disabled')
setSecond.setAttribute('disabled','disabled')
//改變button樣式讓其能夠呼叫中斷時間的方法
const start = document.getElementById("start")
const reset = document.getElementById("reset")
start.innerHTML ="暫停"
start.setAttribute('onclick','stopCounting()')
start.setAttribute('class',"btn btn-danger")
reset.setAttribute('onclick','reset()')
reset.innerHTML = "重設"
reset.setAttribute('class',"btn btn-dark")
}
}
此處程式碼看起來稍微冗長一點,原因是因為我們必須同時操縱三個Input欄位的狀態,但其實邏輯並不複雜,首先這個方法是和開始按鈕的Button做連結的,此處我們仍然需要再次接受三個欄位,原因是我們待會需要對其的狀態做操控,並且我們也需要再次接受使用者所輸入的欄位,而這邊其實不需要再次接受,因為透過剛剛onBlur()的方法,我們寫在全域變數裡面的變數一定會是使用者輸入最新的數字,不過再接收一次這樣也可以避免一些意想不到的狀況發生。
而接下來我們需要確認使用者是不是有Input時間,也就是如果時間皆為0的話,那也不需要計時了,所以我們就讓開始按鈕不會去執行任何東西。
而如果能夠執行的話,和上次的文章一樣,我們利用setInterval()以每一秒執行一次的方式執行倒數的方法,並且我們需要讓原本的Input欄位變得無法更改,否則開始倒計時卻還能改變數字會是一個大bug,而我們透過setAttribute()這個方法來實現,此方法是用來操縱HTML元素內的屬性,跟上篇文章只改變value不一樣,也是一個實用的方法。
並且我們還需要改變按鈕鎖定的方法和樣式,將開始改為暫停,還有其onclick會觸發的方法也做修改,到這邊就完成了開始計時!
倒數計時
const audio = new Audio("clock.mp3");
function Check_Time() {
//check到了沒有
if(hour === 0 && second === 0 && minute === 0){
audio.play();
alert("時間到了")
audio.pause()
stopCounting()
return
}
second -=1
if(second === -1 ){ //如果秒數是-1代表減過頭了
second = 59 //換秒
minute-=1 //扣除minute
}
if(minute === -1 ){ //如果秒數是-1代表減過頭了
minute = 59 //換分
hour-=1 //扣除小時
}
let htmlHour = document.getElementById("setHour")
let htmlSecond = document.getElementById("setSecond")
let htmlMinute = document.getElementById("setMinute")
htmlHour.value = hour
htmlMinute.value = minute
htmlSecond.value = second
}
倒數計時時一樣首先要確認的是時間到了沒有,而這次我們加入了簡單的鬧鈴,通過audio這個函式,可以播放鬧鈴聲,記得必須要將想要設置的鬧鈴mp3放到和程式同樣的資料夾才能觸發,時間到之後,我們會觸發停止計時來去做停止之後的邏輯。
而接下來計時的部分也非常簡單,每次都會去做扣除秒數的部分,而如果秒數到達0以下了,我們就將其改為59並且將分減一,而在分的部分也以此類推就好,最後再將改完的時、分、秒重新分配給HTML元素就完成倒數計時的功能了。
暫停計時
function stopCounting(){
clearInterval(timer)
document.getElementById("setHour").removeAttribute('disabled')
document.getElementById("setSecond").removeAttribute('disabled')
document.getElementById("setMinute").removeAttribute('disabled')
const start = document.getElementById("start")
const reset = document.getElementById("reset")
start.innerHTML ="開始"
start.setAttribute('onclick','startCounting()')
start.setAttribute('class',"btn btn-success")
reset.setAttribute('onclick','addMinute()')
reset.innerHTML = "增加一分鐘"
reset.setAttribute('class',"btn btn-primary")
}
此處非常簡單,首先我們將timer清除,再來我們將原本不可更改的input欄位變得可以更改,然後更改暫停按鈕的樣式就可以了,基本上和開始計時沒有兩樣。
重設和增加一分鐘
function addMinute(){
minute +=1
if(minute>59){
minute = 0
hour +=1
}
let htmlHour = document.getElementById("setHour")
let htmlMinute = document.getElementById("setMinute")
htmlHour.value = hour
htmlMinute.value = minute
}
function reset(){
document.getElementById("setHour").value = 0
document.getElementById("setSecond").value = 0
document.getElementById("setMinute").value = 0
stopCounting()
}
這是兩個簡單卻對於整個計時器的完整度不可或缺的功能,首先增加一分鐘就是增加全域變數中minute的個數再將其分配到HTML元素就好,但我們還必須注意小時數的增加,所以必須在其要加到60的時候去設置讓小時數加一,而我們也可以用同樣的道理去設置增加十分鐘、增加二十分鐘等等
再來則是重置,重置一樣是更改HTML裡的元素全部設為0,之後再去觸發停止計時的按鈕就可以完成重設了。
到此我們就完成整個計時器的功能了,是不是非常簡單呢!看似簡單其實卻運用了很多JavaScript的各個功能,以上就是JavaScript計時器的教學了。
你接下來想看什麼樣的實作作品呢!歡迎留言在下方給我,我都一定會回覆並且寫出更好品質的教學給各位喔!