A simple practice button where pressing + makes the number go up, pressing − makes it go down, and if it goes below zero it turns red so it’s easy to notice.
+ボタンを押すと数字が増えて、−ボタンを押すと数字が減り、もしマイナスになったら赤色でわかりやすく表示されるシンプルな練習用ボタンです。
学ぶこと:状態(数値)の保持とテキスト更新
最小要件:+
/−
で数値が変化、0
未満は赤表示
HTML
<div class="counter" role="group" aria-label="カウンター">
<button id="decrement" type="button" aria-label="1 減らす">−</button>
<!-- aria-live=\"polite\" で画面リーダーにも数値変化を伝える -->
<span id="display" class="display" aria-live="polite">0</span>
<button id="increment" type="button" aria-label="1 増やす">+</button>
</div>
CSS
.counter {
display: inline-flex;
align-items: center;
gap: 1rem;
border: 1px solid #ccc;
border-radius: 8px;
padding: 1rem;
}
.display {
min-width: 4ch; /* 2桁以上でも崩れにくい */
text-align: right;
font-variant-numeric: tabular-nums; /* 桁揃え */
font-size: 2rem;
}
.negative { color: #c0392b; } /* 0未満は赤表示 */
button {
font-size: 1.2rem;
padding: .5rem .9rem;
border-radius: 6px;
border: 1px solid #aaa;
background: #f5f5f5;
cursor: pointer;
}
button:active { transform: translateY(1px); }
JavaScript
// 1) 状態(アプリの今の値)を用意する
let count = 0; // 初期値
// 2) 画面(DOM)から必要な要素を取得
const displayEl = document.getElementById('display');
const incBtn = document.getElementById('increment');
const decBtn = document.getElementById('decrement');
// 3) 状態 → 画面へ反映する関数(レンダー関数)
function render() {
displayEl.textContent = count; // 数字を表示
displayEl.classList.toggle('negative', count < 0); // 0未満なら赤
}
// 初期描画
render();
// 4) ボタンクリックで状態を更新 → 画面を再描画
incBtn.addEventListener('click', () => {
count = count + 1; // 状態を更新
render(); // 画面へ反映
});
decBtn.addEventListener('click', () => {
count = count - 1; // 状態を更新
render(); // 画面へ反映
});
// 学習ポイント:
// ・状態(count)は必ずrender()を通してDOMに反映する(見通しが良くなる)
// ・色の切替はclass付け替えに任せ、見た目の定義はCSSに分離する
このサンプルは「状態(count)という数字を1つだけ持ち、その数字を 画面に映す・ボタンで変えるという最小構成」です。 学ぶポイントは「状態を1か所で管理し、画面更新のやり方を1本にまとめる」ことです。
<button id="decrement">−</button>
と
<button id="increment">+</button>
<span id="display">0</span>
aria-live="polite"
を付けると画面リーダーが変化を読み上げやすくなります。全体を包む <div class="counter">
は、ボタンと表示を横並びに整える箱です(CSSで見た目を調整)。
.counter { display: inline-flex; gap: 1rem; ... }
.display { font-variant-numeric: tabular-nums; text-align: right; }
.negative { color: #c0392b; }
let count = 0;
が「今の数字」の唯一の元データ(単一の真実)です。render()
が count
を画面へ映します。displayEl.textContent = count;
と、displayEl.classList.toggle('negative', count < 0);
の2つだけ。 条件(0未満)を満たすときだけ negative
クラスが付き、色が赤になります。+
ボタンは count = count + 1;
、−
ボタンは count = count - 1;
とし、必ず最後に render()
を呼んで画面を最新状態にします。count
を変えて render()
で映す、という順番を徹底すると大きくなっても迷子になりません。render()
に一本化しておけば、UIを増やす(リセットボタンやキーボード操作)ときも最後に render() だけ呼べばOK になります。count = count + 1
は数値の足し算ですが、DOMから文字列を読んで足すと「連結」になりやすいです。このサンプルでは状態をJS変数だけで管理しているので安全です。render()
の呼び出しを確認しましょう。textContent
や classList.toggle()
を使うと安全・明快です。count = 0; render();
を呼ぶだけで実装できます。localStorage.setItem('count', String(count));
。count = Number(localStorage.getItem('count') ?? 0);
で読み込み。ArrowUp
で+、ArrowDown
で− などを
keydown
イベントで追加可能。Math.max(min, Math.min(max, count + step))
の形で制御。aria-label
を付け、表示には aria-live
を用意済み。フォーカス移動やキーボード操作も加えるとより親切です。まとめると、「状態を決める → 画面に映す関数を1つにまとめる → 操作で状態を変えたら毎回その関数を呼ぶ」の3点が基本です。 この型を覚えると、もっと複雑なUIでもスムーズに組み立てられるようになります。