HOME / BLOG
BLOG

JavaScriptでバスケのスコアカウンターを作る方法

デフォルト画像

バスケのスコアカウンターは、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
ここにCodePenのEmbedコードを貼り付けます。Pen作成後、このブロックと埋め込みタグを差し替えてください。

CodePenに貼る場合は、HTMLパネルへmain要素、CSSパネルへCSS、JSパネルへJavaScriptをそのまま入れます。外部ライブラリは不要です。

よくある失敗

  • ボタンごとに別々の関数を書きすぎて、HOMEとAWAYの処理が重複する
  • data属性の値を文字列のまま足してしまい、数値加算にならない
  • -1を押したときに点数がマイナスになる
  • 表示更新用の関数を作らず、どこで画面が変わるのか追いづらくなる

応用

  • クォーターごとの点数を保存する
  • タイマーを追加して試合時間を表示する
  • ファウル数やタイムアウト数もカウントする
  • localStorageでリロード後もスコアを残す

関連リンク

まとめ

スコアカウンターは、状態を持つ、ボタンで更新する、画面へ反映する、というJavaScriptの基本がきれいに学べます。最初は点数だけで作り、慣れてきたらタイマーやクォーター管理を足すと、実用寄りのツールにできます。