JS30 Day 29 筆記


Posted by GL on 2023-05-23

目標

製作一個倒數計時器

Demo

step 1 : 取得 HTML 頁面元素

const timerDisplay = document.querySelector('.display__time-left');
const endTime = document.querySelector('.display__end-time');
const buttons = document.querySelectorAll('[data-time]');

step 2 : 監聽倒數固定時間按鈕們的 click 的事件

function startTimer() {
  // 拿到 button 中的 data-time 資料(秒數)
  // 并將資料從字串改爲數字型別改爲
  const seconds = parseInt(this.dataset.time);
  // 拿到的秒數傳入 timer function
  timer(seconds);
}

// 監聽每個按鈕的 click 事件,點擊後出發 startTime function
buttons.forEach(button => button.addEventListener('click', startTimer));

step 3 : 建立 timer function

  • Date.now()new Date().getTime():回傳自 1970/01/01 00:00:00 UTC 起經過的毫秒數
  • setInterval() : 指定的時間間隔(以毫秒為單位)執行 callback - function
  • clearInterval():清除 setInterval() 設定
    特定秒數僅執行一次函數,用 setTimeout();重複執行,則用 setInterval() 方法。
  • window.requestAnimationFrame(): 傳入一個callback,並會自動以瀏覽器的頻率更新
let countdown; 

function timer(seconds) {
  // 清除現有的計時器
  clearInterval(countdown);
  // 取得當前的時間
  const now = Date.now();
  // 目前時間後加上輸入的時間,即可拿到倒數開始到倒數後的時間間隔
  // 因為 now 單位是毫秒,因此 seconds 要 * 1000 換算成毫秒
  const timeStamp = now + seconds * 1000;

  // 顯示倒數剩下的時間
  displayTimeLeft(seconds);
  // 顯示倒數結束時預計的時間
  displayEndTime(timeStamp);

  // setInterval()會返回一個 intervalID,此 ID 存到變數countDown,當 clearInterval()時可知道要停止的是 哪個setInterval()。
  countdown = setInterval(() => {
    // 拿到倒數距離當下時間的間隔
    const secondsLeft = Math.round((timeStamp - Date.now()) / 1000);
    // 若倒數剩餘時間小於零,清除這個 setInterval 的計時設定
    if(secondsLeft < 0) {
      clearInterval(countdown);
      return;
    }
    // 更新倒數剩下的時間
    displayTimeLeft(secondsLeft);
    // 每一秒執行一次
  }, 1000);

}


function displayTimeLeft(seconds) {
  // 取得分鐘數的值(秒數 / 60)
  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) {
  // 傳入參數 timestamp 取得 date 物件的資訊
  const end = new Date(timestamp);
  // getHours() 拿到小時數
  const hour = end.getHours();
  // 24小時轉換為 12 小時制
  const adjustedHour = hour > 12 ? hour - 12 : hour;
  // getMinutes() 拿到分鐘數
  const minutes = end.getMinutes();
  // 優化顯示結束的時間
  endTime.textContent = `Be Back At ${hour}:${minutes < 10 ? '0' : ''}${minutes}`;
}

step 4 : 建立自訂倒數

// 透過 form 的 name 為 customForm 選取 form 之後,監聽 submit 事件  
document.customForm.addEventListener('submit', function(e) {
  e.preventDefault();
  // 拿到 input 欄位且 name 為 minutes 的 value,并轉成數字
  const mins = parseInt(this.minutes.value)
  // 判斷輸入的值是否問數字,是的話
  // 才將變數 mins 的資料從“分” 變成“秒”,並傳入 timer function
  if(mins){
    timer(mins * 60)
    // clear input 的 value
    this.reset()
  }
})

參考資料:


#JS 30







Related Posts

【JS學習筆記】如何檢查物件的屬性?

【JS學習筆記】如何檢查物件的屬性?

Web開發學習筆記11 — DOM、Attribute與Property的差異

Web開發學習筆記11 — DOM、Attribute與Property的差異

CSS 預處理器是什麼?

CSS 預處理器是什麼?


Comments