「JavaScript 30」學習筆記(廿九)

前言

本文為「JavaScript 30」教學影片的學習筆記。

目標

製作一個倒數計時器。

筆記

建立一個計數器的指標。

1
let countdown;

選取倒數時間文字。

1
const timerDisplay = document.querySelector('.display__time-left');

選取結束時間文字。

1
const endTime = document.querySelector('.display__end-time');

選取所有設有 data-time 屬性的按鈕。

1
const buttons = document.querySelectorAll('[data-time]');

建立一個 timer() 方法,以倒數計時。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
// 如果剩餘秒數小於 0 就停止計數器
if (secondsLeft < 0) {
clearInterval(countdown);
return;
}
// 顯示剩餘秒數
displayTimeLeft(secondsLeft);
}, 1000);
}

建立一個 displayTimeLeft() 方法,以顯示剩餘時間。

1
2
3
4
5
6
7
8
9
10
11
12
function displayTimeLeft(seconds) {
// 換算成分鐘
const minutes = Math.floor(seconds / 60);
// 剩餘秒數
const remainSeconds = seconds % 60;
// 要顯示的時間格式
const display = `${minutes}:${remainSeconds < 10 ? '0' : ''}${remainSeconds}`;
// 更改倒數時間文字
timerDisplay.textContent = display;
// 更改頁面標題
document.title = display;
}

建立一個 displayEndTime() 方法,以顯示結束時間。

1
2
3
4
5
6
7
8
9
10
11
12
function displayEndTime(timestamp) {
// 轉換結束時間格式
const end = new Date(timestamp);
// 取得結束時間小時
const hour = end.getHours();
// 結束時間小時轉換為 12 小時制
const adjustedHour = hour > 12 ? hour - 12 : hour;
// 取得結束時間分鐘
const minutes = end.getMinutes();
// 更改結束時間文字
endTime.textContent = `Be Back At ${adjustedHour}:${minutes < 10 ? '0' : ''}${minutes}`;
}

建立一個 startTimer() 方法,以開始倒數計時。

1
2
3
4
5
6
function startTimer() {
// 取得按鈕 dataset 的分鐘
const seconds = parseInt(this.dataset.time);
// 執行 timer() 方法
timer(seconds);
}

監聽所有按鈕,當發生 click 行為時,觸發 startTimer() 方法。

1
buttons.forEach(button => button.addEventListener('click', startTimer));

監聽表單,當發生 submit 行為時,觸發閉包。

1
2
3
4
5
6
7
8
9
10
document.customForm.addEventListener('submit', function (e) {
// 防止表單送出並刷新頁面
e.preventDefault();
// 取得輸入的分鐘
const mins = this.minutes.value;
// 執行 timer() 方法
timer(mins * 60);
// 清除輸入的分鐘
this.reset();
});