JavaScriptで1秒ごとに数字が減っていくカウントダウンを作りたいとき、どんな書き方をすればいいのでしょうか。
この記事では、setTimeout
を使って「1秒ごとに数字を減らす」仕組みをわかりやすく紹介します。
コードの流れを追いながら、カウントダウンが動く仕組みを理解していきましょう。
動きをチェック
スタートを押すとカウントダウンが始まります。
リセットを押すと最初の状態に戻ります。
コード
<button id="startBtn">スタート</button>
<button id="resetBtn" disabled>リセット</button>
<p></p>
<script>
const startBtn = document.querySelector('#startBtn');
const resetBtn = document.querySelector('#resetBtn');
const p = document.querySelector('p');
let time = 5;
p.textContent = time;
function countDown() {
startBtn.disabled = true;
if (time > 0) {
p.textContent = time;
time--;
setTimeout(countDown, 1000);
} else {
p.textContent = 0;
resetBtn.disabled = false;
}
}
function resetTime() {
time = 5;
p.textContent = 5;
startBtn.disabled = false;
resetBtn.disabled = true;
}
startBtn.addEventListener('click', countDown);
resetBtn.addEventListener('click', resetTime);
</script>
解説
1. 初期設定
const startBtn = document.querySelector('#startBtn');
const resetBtn = document.querySelector('#resetBtn');
const p = document.querySelector('p');
let time = 5;
p.textContent = time;
startBtn
と resetBtn
でボタンを取得し、p
で <p>
要素を取得しています。time
という変数に 5 を代入し、最初に画面に 5 を表示しています。
2. カウントダウンの処理
function countDown() {
startBtn.disabled = true;
if (time > 0) {
p.textContent = time;
time--;
setTimeout(countDown, 1000);
} else {
p.textContent = 0;
resetBtn.disabled = false;
}
}
「スタート」ボタンを押すと countDown()
が実行されます。
最初に startBtn.disabled = true;
でスタートボタンを無効化し、連打を防いでいます。
if (time > 0)
の中では、現在の time
を表示し、1 減らしたあと、setTimeout(countDown, 1000)
で 1 秒後にもう一度 countDown を実行 しています。
このように、自分自身の関数を再び呼び出す書き方を「再帰関数(さいきかんすう)」といいます。
再帰関数は、同じ処理を一定間隔や一定回数くり返したいときに使われます。
time
が 0 になると、else
の中が実行されて「リセット」ボタンが有効になります。
3. リセットの処理
function resetTime() {
time = 5;
p.textContent = 5;
startBtn.disabled = false;
resetBtn.disabled = true;
}
「リセット」ボタンを押すと、カウントを 5 に戻し、表示をリセットします。
同時にスタートボタンを再び押せるようにして、リセットボタンを無効化します。
4. イベントの設定
startBtn.addEventListener('click', countDown);
resetBtn.addEventListener('click', resetTime);
それぞれのボタンがクリックされたときに、対応する関数を実行するよう設定しています。
まとめ
このコードでは、setTimeout
と再帰関数を組み合わせて、1 秒ごとに数字を減らすカウントダウンを実現しています。setTimeout
は一度だけ実行を予約する関数ですが、再帰的に呼び出すことで、繰り返し動くタイマーのような処理を作ることができます。