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按钮分数只增加一次,后续点击完全没反应:
点击后的界面:
问题原因
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
相关产品推荐
相关产品推荐

