JavaScript30
第二十九天要實作的專案是一個計時器網頁,可以讓使用者選擇要倒數的時間
Github 檔案位置:29 - Countdown Timer
網站的樣子
可以先看看最後的成果
第一步一樣是先選取好要操作的元素並加上監聽,接下來我們先實作倒數計時器的函式
const timerDisplay = document.querySelector('.display__time-left');
const endTime = document.querySelector('.display__end-time');
const buttons = document.querySelectorAll('[data-time]');
function timer(seconds) {
}
function startTimer() {
}
buttons.forEach(button => button.addEventListener('click', startTimer));
這裡以之前學過的 Date 獲取目前時間,加上要倒數的時間算出最後時間後,利用 setInterval
做每 1000 毫秒一次的倒數
備註:Date.now 取出時間的單位為毫秒,因此在 then
中要先將秒數乘上 1000
備註:setInterval
會回傳定時器編號給 countdown,以便後續做清除定時器,避免有多個定時器重複運行
let countdown;
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
countdown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
// check if we should stop it!
if(secondsLeft < 0) {
clearInterval(countdown);
return;
}
console.log(secondsLeft);
}, 1000);
}
function startTimer() {
const seconds = parseInt(this.dataset.time);
timer(seconds);
}
再來要實做的就是將資料渲染至畫面上了,要渲染的是每秒的即時時間倒數,以及最後倒數完的時間
我們要在一開始時就顯示最後停止時間,以及倒數的總時長,隨後就是跟著定時器每秒更新剩餘倒數時長即可
const timerDisplay = document.querySelector('.display__time-left');
const endTime = document.querySelector('.display__end-time');
function timer(seconds) {
// ...
const now = Date.now();
const then = now + seconds * 1000;
displayTimeLeft(seconds);
displayEndTime(then);
countdown = setInterval(() => {
// ...
displayTimeLeft(secondsLeft);
}, 1000);
}
function displayTimeLeft(seconds) {
}
function displayEndTime(timestamp) {
}
先來處理 displayTimeLeft(seconds)
,這裡就以時間的總秒數做除和取餘數的運算,求出剩餘分鐘和剩餘秒數,再將值賦給 timerDisplay
和 document.title
備註:在秒數小於 10 時需在個位數前補零,以三元運算子實現
function displayTimeLeft(seconds) {
const minutes = Math.floor(seconds / 60);
const remainderSeconds = seconds % 60;
const display = `${minutes}:${remainderSeconds < 10 ? '0' : '' }${remainderSeconds}`;
document.title = display;
timerDisplay.textContent = display;
}
再來處理 displayEndTime(timestamp)
,這裡以計算好的 then
目前時間建立 Date
物件,再分別取出十二小時制的小時和分鐘,並賦值至 endTime
中
備註:在分鐘數小於 10 時需在個位數前補零,以三元運算子實現
function displayEndTime(timestamp) {
const end = new Date(timestamp);
const hour = end.getHours();
const adjustedHour = hour > 12 ? hour - 12 : hour;
const minutes = end.getMinutes();
endTime.textContent = `Be Back At ${adjustedHour}:${minutes < 10 ? '0' : ''}${minutes}`;
}
最後再讓我們加上自定義倒數時間的文字輸入框,這裡做的事情比較簡單,讀入輸入後轉換成秒,再呼叫計時器而已
document.customForm.addEventListener('submit', function(e) {
e.preventDefault();
const mins = this.minutes.value;
console.log(mins);
timer(mins * 60);
this.reset();
});
const timerDisplay = document.querySelector('.display__time-left');
const endTime = document.querySelector('.display__end-time');
const buttons = document.querySelectorAll('[data-time]');
let countdown;
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
displayTimeLeft(seconds)
displayEndTime(then)
countdown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
// check if we should stop it!
if(secondsLeft < 0) {
clearInterval(countdown);
return;
}
console.log(secondsLeft);
displayTimeLeft(secondsLeft);
}, 1000);
}
function displayTimeLeft(seconds) {
const minutes = Math.floor(seconds / 60);
const remainderSeconds = seconds % 60;
const display = `${minutes}:${remainderSeconds < 10 ? '0' : '' }${remainderSeconds}`;
document.title = display;
timerDisplay.textContent = display;
}
function displayEndTime(timestamp) {
const end = new Date(timestamp);
const hour = end.getHours();
const adjustedHour = hour > 12 ? hour - 12 : hour;
const minutes = end.getMinutes();
endTime.textContent = `Be Back At ${adjustedHour}:${minutes < 10 ? '0' : ''}${minutes}`;
}
function startTimer() {
const seconds = parseInt(this.dataset.time);
timer(seconds);
}
buttons.forEach(button => button.addEventListener('click', startTimer));
document.customForm.addEventListener('submit', function(e) {
e.preventDefault();
const mins = this.minutes.value;
console.log(mins);
timer(mins * 60);
this.reset();
});
以上是第二十九天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<
Vanilla JS Countdown Timer - #JavaScript30 29/30
[ Alex 宅幹嘛 ] ?? 深入淺出 Javascript30 快速導覽 | Day 29:Countdown Timer
MDN Web Docs