JS カウントダウンタイマーの作り方

イベント開催までの残り日時を表示するカウントダウンタイマーをジャバスクリプトで作ってみたよ。

例:2025年5月3日の大阪万博まで

コード解説

'use strict';
{
  const GOAL = new Date(2025, 4, 3).getTime();

  function refresh() {
    setTimeout(()=>{
      let rest = (GOAL - new Date().getTime()) / 1000;
      document.getElementById('timer').textContent =
        Math.floor(rest / 60 / 60 / 24) + '日' +
        Math.floor(rest / 60 / 60) % 24 + '時間' +
        Math.floor(rest / 60) % 60 + '分' +
        Math.floor(rest) % 60 + '秒';
    if(1 <= rest)refresh();
    },1000);
  }
  
  refresh();
}

最小構成

残り日時は、【開催日時 - 現在の日時】で計算できます。日時は、Date オブジェクトを使います。インスタンス化する時に、引数なしで現在の日時。引数指定時は、【年月】が必須項目です。2025年5月3日を設定するなら new Date(2025,4,3) です。

えぇ、月は【 0月〜】という分かりにくい仕様です。

さて、日時は単純に足し引きできません。【2025年5月3日 - 2000年1月1日】とか、計算ややこしいですよね。そこで、日時をミリ秒単位に変換します。1,000ミリ秒が、1秒です。getTime()メソッドを使います。.でつないでnew Date(2025,4,3).getTime()です。

開催日時 - 現在の日時

とりまconsole.log()を使って、残り時間(ミリ秒)を表示してみましょう。ブラウザの開発ツールを準備。

console.log(
  new Date(2025,4,3).getTime() - new Date().getTime()
  );

無味乾燥な数列が表示されるでしょう。例:35882266994

setTimeout

タイマーID = setTimeout(処理内容,設定時間)を使うと設定時間(ミリ秒)後に処理内容の事柄を実行できます。処理内容はコールバック関数で指定し、関数名のみ記します。関数名に()を付けると関数を即時実行するからです。

const GOAL = new Date(2025, 4, 3).getTime();
function rest(){
  console.log(GOAL - new Date().getTime());
}
rest();
setTimeout(rest,1000);

実行時の残り時間と約1秒後の残り時間が表示されます。

カウントダウン

残り時間を1秒毎に再表示します。そのために1秒毎に自身をコールバックします。また開催日時に到達後はカウントダウンを停止するため、コールバックを呼ぶのは1000ミリ秒以上残り時間がある時とします。

const GOAL = new Date(2025, 4, 3).getTime();
function refresh() {
  setTimeout(()=>{
    let rest = GOAL - new Date().getTime();
    console.log(rest);
    if(1000 <= rest)refresh();
  },1000);
}
refresh();

setTimeout()は、アロー関数を使ってちょっとだけコード減量してみました。

ミリ秒単位のカウントダウンタイマー完成です。

○日○時間○分〇〇秒で表示

ミリ秒単位じゃ、わかりにくい!

わかります。まずは、秒単位で表示してみましょう。

秒単位表示

1,000ミリ秒で1秒なので、ひとまず1,000で割ってみましょう。すると端数がでるので小数点以下を切り捨てます。Math.floor(ミリ秒単位の残り時間 / 1000)

const GOAL = new Date(2025, 4, 3).getTime();
function refresh() {
  setTimeout(()=>{
    let rest = GOAL - new Date().getTime();
    rest = Math.floor(rest / 1000);
    console.log(rest);
    if(1 <= rest)refresh();
  },1000);
}
refresh();

秒単位になったので、コールバックも残り 1秒以上の時です。

秒単位のカウントダウンタイマー完成です。

分・秒単位の表示

秒単位じゃ、わかりにくい!

わかります。では、分・秒単位で表示してみましょう。

1分は 60秒なので、秒単位を 60で割ると分単位。また、その割った余りが残りの秒数。よって、こんなカンジ。

let rest = (GOAL - new Date().getTime()) / 1000,
    min = Math.floor(rest / 60) + '分',
    sec = Math.floor(rest) % 60 + '秒';
console.log(min + sec);

日・時間・分・秒単位の表示

同様に 1時間は 60分なので、分単位を 60で割ると時間単位。また、その割った余りが残りの分数。1日は 24時間なので、時間単位を 24で割ると日単位。また、その割った余りが残りの時間数。まとめると

const GOAL = new Date(2025, 4, 3).getTime();
function refresh() {
  setTimeout(()=>{
    let rest = (GOAL - new Date().getTime()) / 1000,
        days = Math.floor(rest / 60 / 60 / 24) + '日',
        hour = Math.floor(rest / 60 / 60) % 24 + '時間',
        min  = Math.floor(rest / 60) % 60 + '分',
        sec  = Math.floor(rest) % 60 + '秒';
    console.log(days + hour + min + sec);
    if(1 <= rest)refresh();
  },1000);
}
refresh();

HTMLページに表示

JS は、通常 web ページに表示するものなので p タグあたりに,id="timer"属性を付与。textContentに書き出す。ついでに変数も整理。

String(Math.floor(rest) % 60).padStart(2,'0')は、秒を2桁表示に揃えるためのコードです。秒の桁数が変わると見た目が不安定なので。数字を文字列に型変換。padStartの第1引数で2桁表示に。第2引数で秒が1桁時のみ 0 を挿入。

<html><body>
<p id="timer"></p>
<script>'use strict';{
const GOAL = new Date(2025, 4, 3).getTime();

function refresh() {
  setTimeout(()=>{
    let rest = (GOAL - new Date().getTime()) / 1000;
    document.getElementById('timer').textContent =
      Math.floor(rest / 60 / 60 / 24) + '日' +
      Math.floor(rest / 60 / 60) % 24 + '時間' +
      Math.floor(rest / 60) % 60 + '分' +
      String(Math.floor(rest) % 60).padStart(2,'0') + '秒';
    if(1 <= rest)refresh();
  },1000);
}

refresh();
}</script>
</body></html>

'use strict'は、意図どおりに動作させるためのオマジナイ。エラーチェックが厳しくなります。