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

如何移除箭头函数创建的event handler,使游戏达分数上限时按钮失效

解决方案:分数上限后停止按钮累加逻辑

你的问题核心有两个:一是匿名事件回调导致removeEventListener失效,二是游戏结束后没有阻断后续的分数累加流程。下面直接给你修改后的代码和关键说明:

关键修改点

  1. 抽离命名事件处理函数:把原来的匿名箭头函数改成独立的handleButtonClick,保留函数引用,方便后续移除监听或做状态判断。
  2. 游戏状态前置判断:在处理按钮点击时先检查是否已达分数上限,按需决定是否执行加分逻辑。
  3. 完善结束逻辑:在endGame中统一处理按钮禁用或事件移除。

修改后的完整代码

// 假设你已定义以下全局变量
let playerScore = 0;
let computerScore = 0;
const maxScore = 5; // 可自行调整分数上限
const choice = ["rock", "paper", "scissors"];
const gameButtons = document.querySelectorAll(".game-button"); // 替换为你的按钮选择器

// 抽离命名的事件处理函数
function handleButtonClick(e) {
  // 先判断游戏是否已结束
  if (playerScore === maxScore || computerScore === maxScore) {
    // 按需求:仅更新玩家/CPU选择,不累加分数
    const playerSelection = e.target.value;
    document.querySelector(".player-choice").textContent = `Player Chose: ${playerSelection}`;
    const computerSelection = getComputerChoice();
    document.querySelector(".cpu-choice").textContent = `Computer Chose: ${computerSelection}`;
    return; // 跳过加分逻辑
  }

  // 游戏未结束,正常执行流程
  playerSelection = e.target.value;
  playGame();
}

// 绑定事件
gameButtons.forEach(button => {
  button.addEventListener("click", handleButtonClick);
});

function compare(playerSelection, computerSelection) {
  if (playerSelection === computerSelection) { 
    // 平局不加分
  } else if (playerSelection === "rock" && computerSelection === "scissors") {
    playerScore++;
  } else if (playerSelection === "paper" && computerSelection === "rock") {
    playerScore++;
  } else if (playerSelection === "scissors" && computerSelection === "paper") {
    playerScore++;
  } else {
    computerScore++;
  }
  // 更新分数显示
  document.querySelector(".player-score").textContent = `Player score: ${playerScore}`;
  document.querySelector(".cpu-score").textContent = `CPU score: ${computerScore}`;
}

function getComputerChoice() {
  return choice[Math.floor(Math.random() * choice.length)];
}

function playGame() {
  // 更新玩家选择显示
  document.querySelector(".player-choice").textContent = `Player Chose: ${playerSelection}`;
  // 获取并更新CPU选择
  const computerSelection = getComputerChoice();
  document.querySelector(".cpu-choice").textContent = `Computer Chose: ${computerSelection}`;
  // 比较结果并更新分数
  compare(playerSelection, computerSelection);
  // 检查是否结束游戏
  endGame();
}

function endGame() {
  if (playerScore === maxScore) {
    console.log("you won");
    // 若需彻底禁用按钮,取消下方注释
    // gameButtons.forEach(button => {
    //   button.removeEventListener("click", handleButtonClick);
    //   // 或直接禁用按钮:button.disabled = true;
    // });
  } else if (computerScore === maxScore) {
    console.log("you lost");
    // 同上,彻底禁用按钮的逻辑
    // gameButtons.forEach(button => {
    //   button.removeEventListener("click", handleButtonClick);
    // });
  }
}

原方法无效原因

你之前用匿名箭头函数绑定事件,每次addEventListener都会生成全新的函数实例。removeEventListener需要完全匹配的函数引用才能生效,所以之前的调用等于无效操作。抽离成命名函数后,就能保证绑定和移除的是同一个函数。

如果不需要结束后还显示选择,直接在endGame里移除事件监听或禁用按钮即可,这样点击按钮不会有任何反应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:52:56