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

飞镖计分板开发问题:函数重运行前需移除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:03:16