
问题描述与根源分析
在开发基于vanilla javascript和bootstrap的问答游戏时,开发者遇到了一个棘手的问题:当点击了正确的答案按钮后,页面上显示的却是“incorrect!”,并且一个随机的“incorrect”按钮被高亮。这个问题尤其在引入了nextquestion函数来加载下一题后变得明显。
这个问题的根源在于JavaScript事件监听器的累积效应以及对变量作用域的误解。原始代码在每次调用displayQuestion函数时,都会为答案按钮重新添加事件监听器:
// 原始代码中的部分
document.getElementById(`answer${randomArray[0]}`).addEventListener("click", correctAnswer);
document.getElementById(`answer${randomArray[1]}`).addEventListener("click", incorrectAnswer1);
// ... 等等这里的问题在于:
- 监听器累积: 每次加载新问题时,displayQuestion都会调用addEventListener为按钮添加新的监听器。然而,它并没有移除之前为同一按钮添加的旧监听器。这意味着,随着游戏的进行,一个按钮可能会积累多个事件监听器,每次点击都会触发所有这些监听器。
- randomArray的过时引用: randomArray是一个在displayQuestion内部生成的数组,用于随机分配答案到不同的按钮ID(answer1到answer4)。当nextQuestion加载新问题时,displayQuestion会生成一个新的randomArray并更新按钮的文本内容。但是,之前添加的事件监听器在创建时,会“记住”它们所处的randomArray值(通过闭包)。因此,当点击一个按钮时,它可能触发的是一个基于旧randomArray值的监听器,从而导致对当前问题的答案判断错误。例如,如果上一题的正确答案在answer3,而新一题的正确答案在answer1,点击answer3可能仍然会触发旧的correctAnswer逻辑(如果它在上一题确实是正确答案),但此时answer3显示的内容却是新一题的错误答案。
解决方案核心思路:动态判断与统一事件处理
为了解决上述问题,我们需要采取










