iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0
Modern Web

前端藏寶圖系列 第 23

來做一個鐵人賽倒數計時器吧!

前言

呼~鐵人賽終於來到倒數一週的時刻了~/images/emoticon/emoticon42.gif
參加鐵人賽的大家都辛苦了!
為了振奮一下精神,今天來嘗試做一個簡單的倒數計時畫面吧~

HTML: 先準備好標題和倒數時間的部分

<main>
      <h1>iT鐵人賽倒數</h1>
      <div class="countdown">
        <div class="time">
          <h2 class="days">0</h2>
          <span>Days</span>
        </div>

        <div class="time">
          <h2 class="hours">0</h2>
          <span>Hours</span>
        </div>

        <div class="time">
          <h2 class="minutes">0</h2>
          <span>Minutes</span>
        </div>

        <div class="time">
          <h2 class="seconds">0</h2>
          <span>Seconds</span>
        </div>
      </div>
</main>

由於我們要計算時間,所以需要知道幾個必要的概念:

Date 物件

  • 基於世界標準時間 1970 年 1 月 1 日開始
  • 以毫秒來儲存時間 (1000毫秒 = 1 秒)
  • 可以傳入字串指定時間,如果沒有傳入值,則為當下時間

對於Date物件不太熟悉的朋友,可以看看追求JS小姊姊系列- 如果時間能重來,我不想跟工具人聊天

setInterval( function, milliseconds, param1, param2, ...)

  • 第一個參數是 callback function,會依據第二個參數所設定的時間間隔循環,不斷執行下去
  • setInterval本身會回傳一個獨立的 Timer ID,用來傳入clearInterval()

有了這些概念後,就可以開始寫JS的部分了~

JS部分

// 先選取好之後要改的元素
const days = document.querySelector(".days");
const hours = document.querySelector(".hours");
const minutes = document.querySelector(".minutes");
const seconds = document.querySelector(".seconds");

// 傳入字串設定好結束的日期
const endDay = new Date("October 16, 2021 00:00:00");


// 計算距離比賽結束時間
function countTimeLeft() {
  const currentTime = new Date();
  const timeDifference = endDay - currentTime;

  const days = Math.floor(timeDifference / 1000 / 60 / 60 / 24);
  const hours = Math.floor(timeDifference / 1000 / 60 / 60) % 24;
  const minutes = Math.floor(timeDifference / 1000 / 60) % 60;
  const seconds = Math.floor(timeDifference / 1000) % 60;

  return { days, hours, minutes, seconds };
}

計算好時間後,就可以用另一個函式做顯示時間的部分

// 以下寫法會出錯: 必須更新頁面,時間才會更新
// 錯誤原因:每一秒執行的程式是顯示時間的函式,但時間的資料是上次執行拿到的資料
// const timeLeft = countTimeLeft();
// const ID = setInterval(displayCountdown(timeLeft), 1000);


// 以下寫法才可以在每次顯示畫面時拿到新的資料顯示
const ID = setInterval(() => {
  const timeLeft = countTimeLeft();
  displayCountdown(timeLeft);
}, 1000);


function displayCountdown(timeLeft) {
  const passEndDay =
    timeLeft.days <= 0 &&
    timeLeft.hours <= 0 &&
    timeLeft.minutes <= 0 &&
    timeLeft.seconds < 0;

  if (passEndDay) {
    days.innerHTML = "0";
    hours.innerHTML = "0";
    minutes.innerHTML = "0";
    seconds.innerHTML = "0";
    clearInterval(ID);
  } else {
    days.innerHTML = timeLeft.days;
    hours.innerHTML = timeLeft.hours;
    minutes.innerHTML = timeLeft.minutes;
    seconds.innerHTML = timeLeft.seconds;
  }
}


圖片來源:Unsplash

這樣就完成了~~~如果有更好的做法歡迎留言建議~感謝~
/images/emoticon/emoticon41.gif


上一篇
下有對策 - CORS
下一篇
來做一個色碼轉換器吧!
系列文
前端藏寶圖30

2 則留言

0
南國ㄟ安迪
iT邦新手 5 級 ‧ 2021-10-08 20:02:37

Date()的實作!!好棒/images/emoticon/emoticon24.gif

Chiahsuan iT邦新手 4 級 ‧ 2021-10-09 20:46:50 檢舉

/images/emoticon/emoticon25.gif

也參考了你的文章~

0
Hooo
iT邦新手 5 級 ‧ 2021-10-08 23:23:57

看到倒數 7 天心情真好
文青風的倒數實作好厲害!

Chiahsuan iT邦新手 4 級 ‧ 2021-10-09 20:47:24 檢舉

/images/emoticon/emoticon47.gif
我喜歡你的餅乾怪~~~

我要留言

立即登入留言