JavaScript | 1 日 90 分 × 7 日アプリ学習:タイマーアプリ(初級編)

JavaScript
スポンサーリンク

5日目のゴールと今日やること

引用元:なし(本教材はオリジナル解説です)

5日目のテーマは
「タイマーの操作性(UI/UX)を高める」
ことです。

1〜4日目であなたはすでに、

  • setTimeout を使った 1 秒ごとのカウント
  • isRunning による状態管理
  • 開始・停止・リセットの基本動作
  • 00:00 表示の整形

ここまで理解できています。

5日目はここに、

  • ボタンの状態を制御する(開始中は開始ボタンを押せないようにする)
  • タイマーの状態を画面に反映する
  • 「操作ミスを防ぐ」ための UI ロジックを追加する

という、“アプリとしての使いやすさ”を加えていきます。


ボタンの状態を制御するという発想

なぜボタン制御が必要なのか?

今のタイマーは、
開始ボタンを何度押しても動きます。

でも実際のアプリでは、

  • タイマーが動いているときに「開始」を押しても意味がない
  • 停止中に「停止」を押しても意味がない
  • リセット中に「リセット」を押しても意味がない

こうした「無駄な操作」を防ぐ必要があります。

そのために必要なのが、
ボタンの状態(enabled / disabled)を制御する という考え方です。


HTML 側でボタンに ID をつける

ボタンを JavaScript から操作できるようにする

<button id="startBtn" onclick="startTimer()">開始</button>
<button id="stopBtn" onclick="stopTimer()">停止</button>
<button id="resetBtn" onclick="resetTimer()">リセット</button>

これで JavaScript から、

document.getElementById("startBtn")
JavaScript

のようにアクセスできます。


ボタンを無効化(disabled)する方法

disabled = true / false を使う

JavaScript では、
ボタンを無効化するにはこう書きます。

document.getElementById("startBtn").disabled = true;
JavaScript

有効化するには、

document.getElementById("startBtn").disabled = false;
JavaScript

これを使って、
「開始中は開始ボタンを押せない」
「停止中は停止ボタンを押せない」
といった制御を行います。


ボタン状態をまとめて管理する関数を作る

状態管理の考え方を UI にも応用する

タイマーの状態は isRunning で管理していますが、
UI(ボタン)も同じように状態を持たせるとスッキリします。

function updateButtons() {
  document.getElementById("startBtn").disabled = isRunning;
  document.getElementById("stopBtn").disabled = !isRunning;
  document.getElementById("resetBtn").disabled = false;
}
JavaScript

ここでのポイントは、

  • isRunning が true → startBtn は押せない
  • isRunning が false → stopBtn は押せない
  • resetBtn はいつでも押せる

というルールをまとめていることです。

深掘り:なぜ関数にまとめるのか?

開始・停止・リセットのたびに
毎回ボタン状態を手動で書くと、
コードがバラバラになって管理しづらくなります。

updateButtons にまとめることで、

  • どこを直せば UI が変わるかが明確
  • コードの重複がなくなる
  • 状態管理が一箇所に集まる

というメリットがあります。


startTimer にボタン制御を追加する

開始時に UI を更新する

function startTimer() {
  if (isRunning) return;

  isRunning = true;
  updateButtons();

  timerId = setTimeout(tick, 1000);
}
JavaScript

開始した瞬間に、

  • startBtn → disabled
  • stopBtn → enabled

という状態になります。


stopTimer にボタン制御を追加する

停止時に UI を更新する

function stopTimer() {
  if (!isRunning) return;

  clearTimeout(timerId);
  timerId = null;
  isRunning = false;

  updateButtons();
}
JavaScript

停止した瞬間に、

  • startBtn → enabled
  • stopBtn → disabled

になります。


resetTimer にボタン制御を追加する

リセット時は「停止+0に戻す+UI更新」

function resetTimer() {
  if (isRunning) {
    clearTimeout(timerId);
  }

  isRunning = false;
  timerId = null;
  elapsed = 0;

  updateDisplay();
  updateButtons();
}
JavaScript

リセット後は、

  • startBtn → enabled
  • stopBtn → disabled
  • resetBtn → enabled

という状態になります。


5日目のミニ完成版:UI 制御付きタイマー

HTML

<div id="display">00:00</div>

<button id="startBtn" onclick="startTimer()">開始</button>
<button id="stopBtn" onclick="stopTimer()">停止</button>
<button id="resetBtn" onclick="resetTimer()">リセット</button>

JavaScript(重要部分のみ)

let timerId = null;
let isRunning = false;
let elapsed = 0;

function pad(num) {
  return num.toString().padStart(2, "0");
}

function updateDisplay() {
  const totalSeconds = Math.floor(elapsed / 1000);
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;

  document.getElementById("display").innerText =
    pad(minutes) + ":" + pad(seconds);
}

function updateButtons() {
  document.getElementById("startBtn").disabled = isRunning;
  document.getElementById("stopBtn").disabled = !isRunning;
  document.getElementById("resetBtn").disabled = false;
}

function tick() {
  if (!isRunning) return;

  elapsed += 1000;
  updateDisplay();

  timerId = setTimeout(tick, 1000);
}

function startTimer() {
  if (isRunning) return;

  isRunning = true;
  updateButtons();

  timerId = setTimeout(tick, 1000);
}

function stopTimer() {
  if (!isRunning) return;

  clearTimeout(timerId);
  timerId = null;
  isRunning = false;

  updateButtons();
}

function resetTimer() {
  if (isRunning) {
    clearTimeout(timerId);
  }

  isRunning = false;
  timerId = null;
  elapsed = 0;

  updateDisplay();
  updateButtons();
}
JavaScript

5日目で特に深く理解してほしいこと

1つ目:UI も「状態管理」で動かす

isRunning を UI にも反映することで、
アプリ全体の動きが一貫します。

2つ目:ボタン制御は「操作ミスを防ぐ」ために必須

開始中に開始を押せない
停止中に停止を押せない
これだけでアプリの品質が一気に上がります。

3つ目:updateButtons は UI の司令塔

UI の状態を一箇所で管理することで、
コードが読みやすく、修正しやすくなります。


6日目へのつなぎ

6日目からは、

  • タイマーのデザインを整える(CSS)
  • ボタンの見た目をアプリ風にする
  • タイマーのレイアウトを整える

という、“見た目の完成度”を高める段階に入ります。

今日の「UI 制御」ができた時点で、
あなたのタイマーはもう「アプリとしての振る舞い」を持ち始めています。

タイトルとURLをコピーしました