You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS篮球计分板加分函数仅生效一次问题求助

篮球计分板按钮点击仅首次生效问题

我刚接触JS,正在做一个篮球计分板,需求是点击按钮时为对应队伍的分数增加指定数值并更新页面显示。

初始界面:
计分板初始界面

我的HTML代码:

<div class="wrapper">
  <div class="container">
    <h3 class="header-con">HOME</h3>
    <p class="score-text" id="score-home">0</p>
    <div class="btn-wrapper">
      <button class="btn">+1</button>
      <button class="btn">+2</button>
      <button class="btn">+3</button>
    </div>
  </div>
  <div class="container">
    <h3 class="header-con">GUEST</h3>
    <p class="score-text" id="score-guest">0</p>
    <div class="btn-wrapper">
      <button class="btn" id="guest-1">+1</button>
      <button class="btn">+2</button>
      <button class="btn">+3</button>
    </div>
  </div>
</div>

JS代码:

let guestScore = document.getElementById('score-guest')
let homeScore = document.getElementById('score-home')

let guestScoreNumber = 0
let homeScoreNumber = 0

function insreaseBy1(a, b) {
  a += 1
  b.textContent = a
}

document.getElementById('guest-1').onclick = function() {
  insreaseBy1(guestScoreNumber, guestScore)
}

我不想给每个按钮单独写函数,打算用3个通用函数替代6个,但实际运行时,点击+1按钮分数只增加一次,后续点击完全没反应:

点击后的界面:
点击+1后的计分板


问题原因

JS中基本类型(数字、字符串等)是按值传递的,你把guestScoreNumber传给insreaseBy1函数时,传递的是它的副本,不是原变量本身。函数里对a的修改只会影响这个副本,不会改变全局的guestScoreNumber。所以第一次点击后,副本变成1,更新了页面,但全局的guestScoreNumber还是0,后续点击时副本又从0开始加1,页面显示不会变化。

解决方法

方案1:直接操作全局变量

修改函数,让它直接对应全局的分数变量,不用传递基本类型:

let guestScore = document.getElementById('score-guest')
let homeScore = document.getElementById('score-home')

let guestScoreNumber = 0
let homeScoreNumber = 0

// 通用加分函数,指定队伍和加分值
function increaseScore(team, points) {
  if (team === 'guest') {
    guestScoreNumber += points
    guestScore.textContent = guestScoreNumber
  } else if (team === 'home') {
    homeScoreNumber += points
    homeScore.textContent = homeScoreNumber
  }
}

// 绑定所有按钮事件
document.getElementById('guest-1').onclick = () => increaseScore('guest', 1)
// 补充guest+2、guest+3的绑定
document.querySelector('.container:nth-child(2) .btn:nth-child(2)').onclick = () => increaseScore('guest', 2)
document.querySelector('.container:nth-child(2) .btn:nth-child(3)').onclick = () => increaseScore('guest', 3)
// home队伍的按钮绑定
document.querySelector('.container:nth-child(1) .btn:nth-child(1)').onclick = () => increaseScore('home', 1)
document.querySelector('.container:nth-child(1) .btn:nth-child(2)').onclick = () => increaseScore('home', 2)
document.querySelector('.container:nth-child(1) .btn:nth-child(3)').onclick = () => increaseScore('home', 3)

方案2:用对象封装分数(引用类型传递)

因为对象是按引用传递的,修改对象属性会影响原对象,同时可以用事件委托进一步简化代码:

// 用对象存储两队分数
const scores = {
  home: 0,
  guest: 0
}

// 通用加分函数
function increaseScore(team, points) {
  scores[team] += points
  document.getElementById(`score-${team}`).textContent = scores[team]
}

// 事件委托:给父容器绑定一次事件,处理所有按钮点击
document.querySelector('.wrapper').addEventListener('click', (e) => {
  if (e.target.classList.contains('btn')) {
    const team = e.target.dataset.team
    const points = parseInt(e.target.dataset.points)
    increaseScore(team, points)
  }
})

对应的HTML按钮需要补充自定义属性,方便识别队伍和加分值:

<!-- HOME队伍按钮 -->
<button class="btn" data-team="home" data-points="1">+1</button>
<button class="btn" data-team="home" data-points="2">+2</button>
<button class="btn" data-team="home" data-points="3">+3</button>
<!-- GUEST队伍按钮 -->
<button class="btn" data-team="guest" data-points="1">+1</button>
<button class="btn" data-team="guest" data-points="2">+2</button>
<button class="btn" data-team="guest" data-points="3">+3</button>

这种方式只用一个事件监听和一个通用函数,代码更简洁,也方便后续扩展。


内容的提问来源于stack exchange,提问作者slain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 18:07:34