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

FreeCodeCamp Simon游戏重置后点击监听器触发两次问题

Fixing Duplicate Color Entries in Your Simon Game After Reset

Hey there! Let's dig into why clicking color pads is adding two entries to your guessingColors array after restarting the game. This is a super common issue with interactive games, and it almost always boils down to repeated event listeners or missing state resets. Let's break it down step by step:

The Most Likely Culprit: Duplicate Event Listeners

Chances are, every time you start a new game, you're re-binding click event listeners to your color pads—without removing the old ones first. So after a reset and restart, each pad has two (or more) listeners attached. When you click, both listeners fire, pushing the color twice into guessingColors.

How to Fix It

There are a few clean ways to solve this:

1. Bind Listeners Only Once (Recommended)

Move your event binding code outside of your startGame function, so it runs only once when the page loads. Then use a game state flag to control whether clicks should register:

// Define a global flag to track if the game is active
let isGameActive = false;

// Define your click handler as a named function (not anonymous)
function handleColorClick(e) {
  // Ignore clicks if the game isn't active
  if (!isGameActive) return;
  
  const selectedColor = e.target.dataset.color; // Adjust this to match your element setup
  guessingColors.push(selectedColor);
  // Rest of your click logic (play sound, check guess, etc.)
}

// Bind listeners ONCE when the page loads
document.querySelectorAll('.color-pad').forEach(pad => {
  pad.addEventListener('click', handleColorClick);
});

function reset() {
  clearTimeout(repeating);
  clearTimeout(genColor);
  pickedColors = [];
  guessingColors = [];
  isGameActive = false; // Reset the game state flag
  // Add any other resets (like score, round number, etc.)
}

function startGame() {
  reset(); // Reset first to clear old state
  isGameActive = true; // Activate the game
  // Generate first color, start round logic, etc.
}

2. Remove Listeners in Your Reset Function

If you need to re-bind listeners for some reason, make sure to remove them in reset first. Just note: you can only remove listeners that use named functions (anonymous functions can't be targeted):

function reset() {
  clearTimeout(repeating);
  clearTimeout(genColor);
  pickedColors = [];
  guessingColors = [];
  
  // Remove existing click listeners
  document.querySelectorAll('.color-pad').forEach(pad => {
    pad.removeEventListener('click', handleColorClick);
  });
}

function startGame() {
  reset();
  // Re-bind listeners (only do this if you have a specific reason to)
  document.querySelectorAll('.color-pad').forEach(pad => {
    pad.addEventListener('click', handleColorClick);
  });
  // Start game logic...
}

Other Things to Check

  • Uncleared Timers: Double-check that all timers (not just repeating and genColor) are cleared in reset. If a leftover timer is triggering code that modifies guessingColors, that could also cause duplicates.
  • Accidental Array Duplication: Make sure your startGame function isn't accidentally initializing guessingColors twice or pushing to it automatically without user input.

Give these fixes a try—most likely the duplicate event listeners are the root cause!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:57:07