倒數一天!!!
今日任務: 倒數計時時鐘
倒計時我們可以使用setInterval(),每秒減1
setInterval(() => {
seconds--;
}, 1000);
但是setInterval()在某些情況下會有失準的問題:當心 setInterval 因瀏覽器節流模式嚴重失準
因此下面我們每次執行都重新Date.now()
取得現在時間,再將結束時間 - 現在時間
來避免誤差情形發生。
Date.now()
: 回傳自 1970/01/01 00:00:00 UTC 起經過的毫秒數。function timer(seconds) {
const now = Date.now();
const timeUp = now + seconds * 1000;
setInterval(() => {
const secondsLeft = (timeUp - Date.now()) / 1000;
console.log(secondsLeft);
}, 1000);
}
timer(10);
會有小數
使用Math.round()
函數回傳四捨五入後的近似值。
function timer(seconds) {
const now = Date.now();
const timeUp = now + seconds * 1000;
setInterval(() => {
const secondsLeft = Math.round((timeUp - Date.now()) / 1000);
console.log(secondsLeft);
}, 1000);
}
timer(10);
clearInterval(intervalID)
: 取消setInterval()
的重複動作。
setInterval()
會返回一個intervalID
,我們將它存進變數countDown裡面,之後可以讓clearInterval()
知道是要停止哪個setInterval()
。
let countDown;
function timer(seconds) {
const now = Date.now();
const timeUp = now + seconds * 1000;
countDown = setInterval(() => {
const secondsLeft = Math.round((timeUp - Date.now()) / 1000);
if(secondsLeft < 0){
clearInterval(countDown);
return;
}
console.log(secondsLeft);
}, 1000);
}
setInterval()
的定義是每[一段時間(毫秒)]執行一次,所以不會立刻執行,會停[一段時間]才開始執行。
此setInterval每1秒執行一次,會停1秒才開始執行,
我們希望一打開馬上開始執行,所以我們再開一個函式。
function timer(seconds) {
const now = Date.now();
const timeUp = now + seconds * 1000;
displayTimeLeft(seconds);
countDown = setInterval(() => {
const secondsLeft = Math.round((timeUp - Date.now()) / 1000);
if (secondsLeft < 0) {
clearInterval(countDown);
return;
}
displayTimeLeft(secondsLeft);
}, 1000);
}
function displayTimeLeft(seconds){
console.log(seconds);
}
timer(10);
const timeLeft = document.querySelector('.display__time-left');
function displayTimeLeft(seconds){
const mins = Math.floor(seconds / 60);
const remainderSecs = seconds % 60;
timeLeft.textContent = `${mins}:${remainderSecs}`;
}
function displayTimeLeft(seconds){
const mins = Math.floor(seconds / 60);
const remainderSecs = seconds % 60;
timeLeft.textContent = `${mins}:${remainderSecs < 10 ? '0' : ''}${remainderSecs}`;
}
Document.title
: 設置網頁的標題
function displayTimeLeft(seconds){
...
const display = `${mins}:${remainderSecs < 10 ? '0' : ''}${remainderSecs}`;
timeLeft.textContent = display;
document.title = display;
}
new date(milliseconds)
:傳入的參數是一個數字,值表示從 1970-01-01 00:00:00 UTC (格林威治標準時間) 開始累計到某時間點的毫秒數 (milliseconds)。Date.prototype.getHours()
: 根據本地時間返回指定日期的小時 ( 0-23 )。Date.prototype.getMinutes()
: 根據本地時間返回指定日期的分鐘 ( 0-59 )。
const endTime = document.querySelector('.display__end-time');
function timer(seconds) {
...
displayTimeLeft(seconds);
diplayEndTime(timeUp);
countDown = setInterval(() => {
...
}, 1000);
}
function diplayEndTime(timeUp) {
const end = new Date(timeUp);
const hours = end.getHours();
const mins = end.getMinutes();
endTime.textContent = `結束時間:${hours}:${mins < 10 ? '0' : ''}${mins}`;
}
function diplayEndTime(timeUp) {
const end = new Date(timeUp);
const hours = end.getHours();
const mins = end.getMinutes();
const AmPmHours = hours < 12 ? `上午${hours}` : `下午${hours - 12}`;
endTime.textContent = `結束時間:${AmPmHours}:${mins < 10 ? '0' : ''}${mins}`;
}
const timeBtns = document.querySelectorAll('[data-time]');
timeBtns.forEach((btn) => btn.addEventListener('click', startTimer));
function startTimer() {
const seconds = parseInt(this.dataset.time); //將dataset字串轉成數字
timer(seconds);
}
連續按按鈕畫面會亂閃,setInterval()太多個,開頭先清除掉所有setInterval
function timer(seconds) {
clearInterval(countDown); //開頭先清除掉所有setInterval
const now = Date.now();
const timeUp = now + seconds * 1000;
displayTimeLeft(seconds);
diplayEndTime(timeUp);
countDown = setInterval(() => {
...
}, 1000);
}
Document.forms
:
<form>
元素的列表。const selectForm = document.forms[index];
const selectFormElement = document.forms[index].elements[index];
document.forms.customForm
:取得表單名稱為customForm的表單集合
e.preventDefault()
:如果事件可以被取消,就取消事件(即取消事件的預設行為)。但不會影響事件的傳遞,事件仍會繼續傳遞。
document.customForm.addEventListener('submit', inputTime);
function inputTime(e) {
e.preventDefault();
const secs = this.minutes.value * 60; //將輸入的數字分鐘數轉成秒數
timer(secs);
this.reset(); //清空表單
}
今日學習到的:
setInterval()
:
intervalID
,之後可以讓clearInterval()
知道是要停止哪個setInterval()
。clearInterval(intervalID)
: 取消setInterval()
的重複動作。Date.now()
: 回傳自 1970/01/01 00:00:00 UTC 起經過的毫秒數。new date(milliseconds)
:傳入的參數是一個數字,值表示從 1970-01-01 00:00:00 UTC (格林威治標準時間) 開始累計到某時間點的毫秒數 (milliseconds)。Date.prototype.getHours()
: 根據本地時間返回指定日期的小時 ( 0-23 )。Date.prototype.getMinutes()
: 根據本地時間返回指定日期的分鐘 ( 0-59 )。Math.round()
函數回傳四捨五入後的近似值。Document.title
: 設置網頁的標題Document.forms
:
<form>
元素的列表。document.forms.customForm
:取得表單名稱為customForm的表單集合e.preventDefault()
:如果事件可以被取消,就取消事件(即取消事件的預設行為)。但不會影響事件的傳遞,事件仍會繼續傳遞。效果連結:連結
參考連結:
MDN: Date
JavaScript Date 時間和日期 - Fooish 程式技術
MDN: Document.forms
JavaScript - 表單元素- Form Element - KingKong Bruce記事
MDN: Event.preventDefault()
JS30