JavaScript测验分数异常:最后一题分数未在Alert弹窗前更新
问题分析与解决
问题根源
问题出在两个核心点:
alert()是同步阻塞式弹窗,执行时会暂停浏览器所有DOM渲染和JS运行,导致最后一题更新的分数还没来得及在页面显示,就被弹窗直接挡住。endGame()里直接调用了restartGame(),关闭弹窗后分数立刻被重置为0,用户根本看不到最后一题的分数变化结果。
解决方案
- 让浏览器先完成分数的DOM渲染,再弹出胜负提示
- 由用户主动触发游戏重启,避免分数被立刻清空
修改后的代码示例
JavaScript部分
function loadQuestion() { const currentQuestion = questionsAnswers[questionIndex]; document.getElementById("question-box").innerHTML = currentQuestion.question; } let correctScore = 0; let incorrectScore = 0; function checkAnswer(selectedAnswer) { const currentQuestion = questionsAnswers[questionIndex]; const correctAnswer = currentQuestion.correctAnswer; if (selectedAnswer === correctAnswer) { correctScore++; } else { incorrectScore++; } // 更新页面分数显示 document.getElementById("correct-score").textContent = correctScore; document.getElementById("incorrect-score").textContent = incorrectScore; questionIndex++; if (questionIndex < questionsAnswers.length) { loadQuestion(); } else { // 延迟执行弹窗,确保DOM渲染完成 setTimeout(endGame, 0); } } function endGame() { const message = correctScore === 10 ? "恭喜你,全部答对!" : `很遗憾,你答对了${correctScore}/10题,要不要再试一次?`; // 弹窗确认后再重启游戏 if (confirm(message)) { restartGame(); } } function restartGame() { questionIndex = 0; correctScore = 0; incorrectScore = 0; document.getElementById("correct-score").textContent = correctScore; document.getElementById("incorrect-score").textContent = incorrectScore; loadQuestion(); }
补充HTML优化建议
可以添加一个手动重启按钮,避免用户关闭弹窗后无法继续游戏:
<div id="question-box"></div> <div class="score-display"> 正确: <span id="correct-score">0</span> | 错误: <span id="incorrect-score">0</span> </div> <div class="answer-buttons"> <button onclick="checkAnswer(true)">True</button> <button onclick="checkAnswer(false)">False</button> </div> <button onclick="restartGame()" style="display:none" id="restart-btn">重新开始</button>
对应修改endGame函数,显示重启按钮:
function endGame() { const message = correctScore === 10 ? "恭喜你,全部答对!" : `很遗憾,你答对了${correctScore}/10题,要不要再试一次?`; alert(message); document.getElementById("restart-btn").style.display = "inline-block"; }
关键说明
setTimeout(endGame, 0):将弹窗逻辑推迟到浏览器下一个渲染周期执行,确保分数已经在页面更新完成。- 手动触发重启:无论是用
confirm弹窗确认,还是显示重启按钮,都能保证用户先看到最终分数,再决定是否重新开始游戏。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

