JavaScript | 1 日 90 分 × 7 日アプリ学習:強化版カウンターアプリ(初級編)

JavaScript
スポンサーリンク

1日目のゴールと今日のテーマ

1日目のテーマは「シンプルだけど“設計の考え方”が入ったカウンターアプリを作ること」です。
ただの「+1ボタン」ではなく、

複数ボタンを持つ。
ボタンごとに役割を分ける(イベント分離)。
数値の管理をきちんと1か所で行う。

この3つを意識して作ります。

今日の最終ゴールは:

+1 / −1 / リセットの3ボタンでカウンターを操作できる。
0未満にならないように防止できる。
「ボタンの処理」と「数値の管理」を分けて考えられる。

ここまで行ければ、初級の1日目としてはかなりいい仕上がりです。


まずは「カウンターアプリ」の全体像をイメージする

画面に欲しいものを言葉で整理する

今日作るカウンターアプリには、最低限こんな要素が必要です。

現在の数値を表示する場所。
+1ボタン。
−1ボタン。
リセットボタン。

例えば、こういう見た目です。

0
[ +1 ] [ −1 ] [ リセット ]

さらに、「0未満防止」を入れるので、

0のときに −1 を押しても、0のまま。
−1 には絶対ならない。

という動きにします。

HTML の最小構成を用意する

HTML はこんな感じを想定します。

<div id="counter">0</div>

<button id="btn-plus">+1</button>
<button id="btn-minus">−1</button>
<button id="btn-reset">リセット</button>

JavaScript からは、この3つのボタンと、「#counter」の表示部分を操作します。


数値管理:カウンターの“本当の値”はどこに置く?

表示と「本当の値」は分けて考える

カウンターアプリでよくやりがちな間違いがあります。

表示されている文字(”0″ とか “1”)を直接読んで計算する。

例えば:

const counterEl = document.getElementById("counter");
let value = Number(counterEl.textContent);
value = value + 1;
counterEl.textContent = value;
JavaScript

これは動くのですが、設計としてはイマイチです。
なぜかというと、「状態」が HTML の中に散らばってしまうからです。

今日は、「表示」と「本当の値」を分けるやり方を学びます。

変数で「本当の値」を持つ

JavaScript の中に、カウンター用の変数を用意します。

let count = 0;
JavaScript

これが「本当の値」です。
画面には、この count を“映しているだけ”にします。

表示を更新する関数を作っておきます。

const counterEl = document.getElementById("counter");

function render() {
  counterEl.textContent = count;
}
JavaScript

最初に一度呼んでおきます。

render();
JavaScript

ここでの重要ポイントは、

画面は「state(状態)」を映すだけ。
状態の本体は JavaScript の変数(count)にある。

という考え方です。
これが、後々アプリを大きくしていくときの土台になります。


複数ボタンとイベント分離の考え方

ボタンごとに「やること」を整理する

3つのボタンは、それぞれ役割が違います。

+1ボタン:count に 1 足す。
−1ボタン:count から 1 引く(ただし 0未満は禁止)。
リセットボタン:count を 0 にする。

まずは、HTML からボタンを取得します。

const plusButton = document.getElementById("btn-plus");
const minusButton = document.getElementById("btn-minus");
const resetButton = document.getElementById("btn-reset");
JavaScript

次に、クリックイベントを設定します。

plusButton.addEventListener("click", handlePlus);
minusButton.addEventListener("click", handleMinus);
resetButton.addEventListener("click", handleReset);
JavaScript

ここで大事な設計ポイントは、

「その場で無名関数を書かず、処理を別の関数に分けている」
ということです。

なぜイベント分離が大事なのか

例えば、こう書くこともできます。

plusButton.addEventListener("click", () => {
  count = count + 1;
  render();
});
JavaScript

これも動きますが、ボタンが増えたりロジックが複雑になったりすると、
どこで何をしているかが分かりづらくなります。

一方、こう書いておけば:

plusButton.addEventListener("click", handlePlus);
JavaScript

「handlePlus に、+ボタンの仕事が集まっている」ということが一目で分かります。
設計として、“責務の分離”ができている状態です。


+1 / −1 / リセットのロジックを書く

+1ボタンの処理

function handlePlus() {
  count = count + 1;
  render();
}
JavaScript

ここでやっていることは、とてもシンプルです。

count を 1 増やす。
画面を最新の count に合わせて描き直す。

「状態を変えたら、必ず render を呼ぶ」というルールを決めておくと、
バグが出にくくなります。

−1ボタンの処理(0未満防止)

ここが今日の大事なポイントです。

普通に書くとこうなります。

function handleMinus() {
  count = count - 1;
  render();
}
JavaScript

これだと、0 から −1、−2 とどんどんマイナスになります。
「0未満防止」を入れるには、条件分岐を挟みます。

function handleMinus() {
  if (count === 0) {
    return;
  }

  count = count - 1;
  render();
}
JavaScript

ここでの流れを丁寧に追うと:

count が 0 のときは、何もせずに return(関数を終了)。
0 以外のときだけ、1 減らして render する。

という動きになっています。

別の書き方もあります。

function handleMinus() {
  if (count > 0) {
    count = count - 1;
    render();
  }
}
JavaScript

どちらでも OK です。
大事なのは、「0 未満にしない」という条件を、“マイナスボタンの責務”としてきちんと持たせていることです。

リセットボタンの処理

function handleReset() {
  count = 0;
  render();
}
JavaScript

ここもシンプルです。

count を 0 に戻す。
画面を描き直す。

リセットは、「どんな状態からでも、ちゃんと初期状態に戻せる」ことが大事です。
count だけでなく、もし今後「他の状態」が増えたら、それもここでリセットする場所になります。


0未満防止を「UIで伝える」発想(少し発展)

−ボタンを 0 のときだけ無効にする

ロジックとしては「0未満防止」ができましたが、
ユーザーにとっては、「押しても反応がない」のは少し不親切です。

少しだけ発展として、
「count が 0 のときは − ボタンを押せない見た目にする」
というアイデアを紹介します。

function updateMinusButtonState() {
  if (count === 0) {
    minusButton.disabled = true;
  } else {
    minusButton.disabled = false;
  }
}
JavaScript

そして、render の中か、render の後にこれを呼びます。

function render() {
  counterEl.textContent = count;
  updateMinusButtonState();
}
JavaScript

これで、

count が 0 のときは − ボタンがグレーアウトして押せなくなる。
1 以上になったら、 − ボタンが押せるようになる。

という挙動になります。

ここでの深掘りポイントは、

ロジックとしても防いでいる(0未満防止)。
UIとしても「押せない状態」を見せている。

という、二重の安全設計になっていることです。
中級に行くための「ちょっといい設計の感覚」です。


1日目のまとめと、次に進むための視点

今日やったことを、言葉で整理します。

カウンターの「本当の値」を変数(count)で管理し、画面はそれを映すだけにした。
ボタンごとにイベントハンドラ(handlePlus / handleMinus / handleReset)を分けて、“イベント分離”した。
+1 / −1 / リセットのロジックを書き、「状態を変えたら必ず render を呼ぶ」流れを作った。
0未満防止の条件分岐を − ボタン側に持たせて、「押してもマイナスにしない」設計にした。
(発展)0 のときだけ − ボタンを disabled にすることで、UIとしても制約を伝える工夫を見た。

2日目以降は、このカウンターに少しずつ“強化要素”を足していきます。
例えば:

+5 / −5 ボタンを追加する。
上限値を決めて、「これ以上は増えない」を入れる。
複数のカウンターを並べて、それぞれ独立して動かす。

など、「数値管理」と「イベント分離」の考え方を使い回していきます。

最後に一つだけ、ちゃんと聞きたい。

今日の中で、「あ、ちょっと気持ちいいな」と感じたのはどこでしたか?
ボタンを押すたびに数字が変わった瞬間か、0 で − を押してもマイナスにならない安心感か。
その「気持ちいい」と感じたところが、あなたと“ロジック設計”の一番の接点です。
そこを意識しながら、2日目の強化に進んでいきましょう。

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