バスケのスコアカウンターは、JavaScriptの状態管理を学ぶ題材としてかなり相性が良いです。HOMEとAWAYの点数を持ち、ボタンを押したら点数を更新するだけなので、最初の自作ツールにも向いています。
この記事では、+1、+2、+3、-1、リセットを備えた簡単なスコアカウンターを作ります。より本格的な試合管理は、NINESのバスケスコア管理ツールも参考にしてください。
作るもの
- HOMEとAWAYのスコア表示
- 1点、2点、3点を加算するボタン
- 押し間違いを戻せる-1ボタン
- 試合前の状態に戻すリセットボタン
- スマホでは縦並びになるレスポンシブレイアウト
HTML
チームごとの点数はoutput要素で表現します。ボタンにはdata-teamとdata-pointを持たせて、JavaScript側でどのチームに何点足すか判定します。
<main class="scoreboard">
<img
class="nines-logo"
src="https://kjnine.com/wp-content/themes/kjnines_theme/images/svg2/nines_logo_wht.svg"
alt="NINES"
>
<section class="team">
<p>HOME</p>
<output id="home-score" class="score">0</output>
<div class="buttons">
<button data-team="home" data-point="1">+1</button>
<button data-team="home" data-point="2">+2</button>
<button data-team="home" data-point="3">+3</button>
<button data-team="home" data-point="-1">-1</button>
</div>
</section>
<section class="center">
<p>BASKETBALL</p>
<strong>SCORE</strong>
<button id="reset">RESET</button>
</section>
<section class="team">
<p>AWAY</p>
<output id="away-score" class="score">0</output>
<div class="buttons">
<button data-team="away" data-point="1">+1</button>
<button data-team="away" data-point="2">+2</button>
<button data-team="away" data-point="3">+3</button>
<button data-team="away" data-point="-1">-1</button>
</div>
</section>
</main>CSS
見た目はスコアボードらしく黒背景にします。数字が主役なので、スコア部分はclamp()で大きくしつつ、画面幅に合わせて自然に縮むようにします。
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
background: #111;
font-family: system-ui, sans-serif;
color: #fff;
}
.scoreboard {
position: relative;
overflow: hidden;
width: min(94vw, 860px);
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: 16px;
padding: 20px;
border: 3px solid #fff;
background: linear-gradient(135deg, #181818, #050505);
}
.nines-logo {
position: absolute;
top: 16px;
right: 18px;
width: 96px;
opacity: .14;
pointer-events: none;
}
.team,
.center {
display: grid;
place-items: center;
gap: 14px;
padding: 24px;
border: 1px solid #3a3a3a;
}
.team p,
.center p {
margin: 0;
color: #ffd93d;
font-weight: 900;
letter-spacing: .12em;
}
.score {
font-size: clamp(56px, 12vw, 112px);
font-weight: 900;
line-height: 1;
}
.center strong {
font-size: clamp(24px, 5vw, 44px);
}
.buttons {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
button {
min-width: 64px;
padding: 12px 16px;
border: 2px solid #fff;
border-radius: 999px;
background: transparent;
color: #fff;
font: inherit;
font-weight: 800;
cursor: pointer;
}
button:hover {
background: #ff2f63;
}
#reset {
border-color: #ffd93d;
color: #ffd93d;
}
@media (max-width: 720px) {
.scoreboard {
grid-template-columns: 1fr;
}
}JavaScript
scoresオブジェクトにHOMEとAWAYの点数を持たせます。ボタンを押すたびに状態を更新し、renderScores()で画面へ反映します。
const scores = {
home: 0,
away: 0
};
const homeScore = document.querySelector("#home-score");
const awayScore = document.querySelector("#away-score");
const pointButtons = document.querySelectorAll("[data-team][data-point]");
const resetButton = document.querySelector("#reset");
function renderScores() {
homeScore.textContent = scores.home;
awayScore.textContent = scores.away;
}
pointButtons.forEach((button) => {
button.addEventListener("click", () => {
const team = button.dataset.team;
const point = Number(button.dataset.point);
scores[team] = Math.max(0, scores[team] + point);
renderScores();
});
});
resetButton.addEventListener("click", () => {
scores.home = 0;
scores.away = 0;
renderScores();
});
renderScores();CodePen埋め込み用エリア
CodePenに貼る場合は、HTMLパネルへmain要素、CSSパネルへCSS、JSパネルへJavaScriptをそのまま入れます。外部ライブラリは不要です。
よくある失敗
- ボタンごとに別々の関数を書きすぎて、HOMEとAWAYの処理が重複する
- data属性の値を文字列のまま足してしまい、数値加算にならない
- -1を押したときに点数がマイナスになる
- 表示更新用の関数を作らず、どこで画面が変わるのか追いづらくなる
応用
- クォーターごとの点数を保存する
- タイマーを追加して試合時間を表示する
- ファウル数やタイムアウト数もカウントする
- localStorageでリロード後もスコアを残す
関連リンク
まとめ
スコアカウンターは、状態を持つ、ボタンで更新する、画面へ反映する、というJavaScriptの基本がきれいに学べます。最初は点数だけで作り、慣れてきたらタイマーやクォーター管理を足すと、実用寄りのツールにできます。
