飞镖计分板开发问题:函数重运行前需移除Event Listeners
飞镖计分板问题解决
你的核心问题是每次切换玩家时重复给按钮绑定点击事件,导致同一个按钮挂着多轮的监听器,后续点击会同时触发旧玩家的逻辑,所以得分乱加。而且你只移除了当前点击按钮的监听器,其他按钮的旧监听器还在运行,自然会出现玩家1的totalArrows疯涨的情况。
正确的做法是只给按钮绑定一次事件,在事件处理函数内部动态获取当前玩家,不用每次切换玩家都重新绑定。修改后的代码如下:
// 玩家对象 // remaining:剩余分数 // totalArrows:已投掷飞镖总数 let player1 = { name: 'Steven', remaining: 501, totalArrows: 0}; let player2 = { name: 'Tom', remaining: 501, totalArrows: 0}; let player3 = { name: 'Nico', remaining: 501, totalArrows: 0}; let players = [player1, player2, player3]; // 计分按钮 const targetButtons = document.querySelectorAll(".target"); let currentPlayerIndex = 0; let throwsInTurn = 0; // 单次点击处理逻辑 function handleTargetClick(e) { if (throwsInTurn >= 3) return; const currentPlayer = players[currentPlayerIndex]; const score = parseInt(e.target.textContent); currentPlayer.totalArrows++; currentPlayer.remaining -= score; throwsInTurn++; // 回合结束,切换玩家 if (throwsInTurn === 3) { currentPlayerIndex = (currentPlayerIndex + 1) % players.length; throwsInTurn = 0; console.log(`回合结束,现在是${players[currentPlayerIndex].name}的回合`); } } // 只绑定一次事件 targetButtons.forEach(button => { button.addEventListener('click', handleTargetClick); }); // 初始化提示 console.log(`游戏开始,首先是${players[currentPlayerIndex].name}的回合`);
关键改动说明:
- 把点击事件从
playerTurn里移出来,只给所有按钮绑定一次监听器,避免重复绑定导致的多逻辑冲突。 - 用
throwsInTurn记录当前回合的投掷次数,变量名更清晰,避免全局混淆。 - 在点击事件内部动态获取当前玩家,每次点击都用最新的
currentPlayerIndex取值,保证得分加到正确的玩家身上。 - 移除了原代码中混乱的
removeEventListener操作,因为现在只绑定一次,不需要反复移除再添加。
这样修改后,每轮3次投掷结束后会自动切换玩家,所有按钮的点击都会正确对应当前玩家的得分,不会再出现旧玩家被累加的情况。
内容的提问来源于stack exchange,提问作者ESDEE
相关产品推荐
相关产品推荐

