首页 > 解决方案 > 防止 addEventListener 在 forEach 循环中再次运行

问题描述

首先,我想知道我对问题原因的看法是否正确。

const updateScore = (isCorrect) => {
  // Update Game Variables
  if (isCorrect === true) {
    counter++;
    score += 100;
  }
};

// Reset Styling
const resetLoadedQuestionStyling = (isCorrect) => {
  questionScreen.style.display = 'none';
  answerArr.forEach(answer => {
    answer.classList.remove('correct');
    answer.classList.remove('wrong');
    answer.classList.remove('disable');
  });
  updateScore(isCorrect);
};

const styleAnswer = (div, isCorrect) => {
  if (isCorrect === true) {
    div.classList.add('correct');
  } else {
    div.classList.add('wrong');
    for (let i = 0; i < answerArr.length; i++) {
      if (i === currentQuestion.correct) {
        answerArr[i].classList.add('correct');
      }
    }
  }

  // Prevent Second Check
  answerArr.forEach(answer => {
    answer.classList.add('disable');
  });

  // Reset Styling
  setTimeout(() => {
    resetLoadedQuestionStyling(isCorrect);
  }, 3000);
};

const checkAnswer = (div, index) => {
  const userChoice = index;
  // Default Answer State
  let isCorrect = false;
  if (userChoice === currentQuestion.correct) {
    isCorrect = true;
  }
  styleAnswer(div, isCorrect);
};

answerArr.forEach((div, index) => {
  div.addEventListener('click', () => {
    checkAnswer(div, index);
  });
});

  1. counter更新了 1 次,那 2 次......我认为这个问题的原因是我EventListener处于一个forEach循环中,对吗?

  2. 如何预防?

谢谢!

编辑:添加了更多代码以使我的想法更好。

编辑: answerArr 是我的 HTML 中的 4 个 div 数组

标签: javascript

解决方案


可能存在与 setTimeout 相关的问题。每次单击答案时,计数器设置为在 3 秒后递增。

这是单击答案时的顺序:

'click'

  checkAnswer ->
    styleAnswer ->
      setTimeout =>
        resetLoadedQuestionStyling ->
          updateScore ->
            counter++

下面是删除了所有不相关行的代码。每次点击后它都会增加计数器,但仅在 3 秒后。

const answerArr = [...document.querySelectorAll('button')];
let counter = 0;
const span = document.getElementById('counter');

const updateScore = (isCorrect) => {
  if (isCorrect === true) {
    counter++
  }
  span.innerText = counter;
}

const resetLoadedQuestionStyling = (isCorrect) => {
  updateScore(isCorrect)
}

const styleAnswer = (div, isCorrect) => {

  // Reset Styling after 3 seconds
  setTimeout(() => {
    resetLoadedQuestionStyling(isCorrect);
  }, 3000);
}

const checkAnswer = (div, index) => {
  styleAnswer(div, true);
}

answerArr.forEach((div, index) => {
  div.addEventListener('click', () => {
    checkAnswer(div, index);
  });
});
<button>Answer 1</button><br>
<button>Answer 2</button><br>
<button>Answer 3</button><br>
<button>Answer 4</button><br>

<p>Counter: <span id="counter"></span></p>


推荐阅读