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

Vanilla JS石头剪刀布:重启时事件监听重复触发问题求助

石头剪刀布游戏重启异常修复方案

核心问题定位

你推测的方向没错,问题确实出在winScreen、tieScreen、loseScreen这几个函数里。每次游戏结束调用这些函数时,都会重新给操作按钮(石头/剪刀/布)绑定click事件监听,而之前绑定的事件并没有被移除。当你重启游戏后,按钮上已经累积了多份事件回调,点击一次就会触发所有绑定的逻辑。

具体修复方法

方法1:初始化时一次性绑定事件(推荐)

把按钮的事件监听移到页面初始化阶段只执行一次,不要在结果屏幕函数里重复绑定:

// 页面加载完成后仅执行一次
document.addEventListener('DOMContentLoaded', function() {
  // 绑定操作按钮的选择逻辑
  const choiceButtons = document.querySelectorAll('.choice-btn');
  choiceButtons.forEach(btn => {
    btn.addEventListener('click', handlePlayerChoice);
  });

  // 绑定重启按钮逻辑
  const restartBtn = document.querySelector('.restart-btn');
  restartBtn.addEventListener('click', restartGame);
});

// 单独抽离玩家选择的逻辑函数
function handlePlayerChoice(e) {
  const playerChoice = e.target.dataset.choice;
  // 这里写生成电脑选择、判断胜负、更新界面等原有逻辑
}

// 重启游戏的统一逻辑
function restartGame() {
  // 重置分数、隐藏结果界面、显示选择界面等操作
}

方法2:绑定前移除旧事件(快速适配现有代码)

如果不想大幅调整结构,可在每次绑定新事件前,先移除按钮上的旧事件回调(注意必须用具名函数,不能用匿名函数):

// 提前定义具名的选择处理函数
function handlePlayerChoice(e) {
  // 原有按钮点击逻辑
}

// 在winScreen/tieScreen/loseScreen中修改事件绑定逻辑
function winScreen() {
  // 其他界面更新逻辑...
  const choiceButtons = document.querySelectorAll('.choice-btn');
  choiceButtons.forEach(btn => {
    btn.removeEventListener('click', handlePlayerChoice);
    btn.addEventListener('click', handlePlayerChoice);
  });
}

额外优化建议

  • 集中管理游戏状态(如当前游戏阶段、分数数据),避免重复初始化导致的逻辑混乱
  • 用统一函数处理界面的显示/隐藏,减少结果屏幕函数中的冗余代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:54:32