
本文详解如何通过 javascript 实现单页测验应用中的题目顺序切换逻辑,包括状态管理、dom 动态渲染、选项绑定与边界控制,确保每次点击“下一题”按钮后准确显示新题目及选项。
本文详解如何通过 javascript 实现单页测验应用中的题目顺序切换逻辑,包括状态管理、dom 动态渲染、选项绑定与边界控制,确保每次点击“下一题”按钮后准确显示新题目及选项。
在构建交互式在线测验(Quiz)应用时,一个核心需求是:用户完成当前题目后,点击「下一题」按钮,页面应立即更新为下一道题及其选项。这看似简单,但若忽略状态同步与 DOM 重绘时机,极易出现“点击无效”“题目不更新”或“索引越界”等问题。
关键问题在于:仅递增 currentQuestionIndex 并不能自动刷新界面——你必须显式调用 displayQuestion() 来重新渲染内容。 原代码中 nextBtn.addEventListener 内只执行了 currentQuestionIndex++,却未触发视图更新,因此界面始终停留在第一题。
以下是完整、健壮的实现方案:
✅ 正确的切换逻辑(含边界保护)
const nextBtn = document.querySelector(".next"); // 确保已正确定义
nextBtn.addEventListener("click", () => {
// 1. 防止越界:检查是否还有下一题
if (currentQuestionIndex < Questions.length - 1) {
currentQuestionIndex++;
displayQuestion(); // ✅ 核心:必须调用此函数刷新 DOM
} else {
// 可选:到达最后一题后显示结果页
showResults();
}
});✅ 改进后的 displayQuestion()(避免重复绑定事件、清理旧内容)
原函数每次调用都会向 .options 容器追加新选项,但未清除历史选项,导致选项堆叠;同时为每个选项重复绑定点击事件,存在内存泄漏风险。优化如下:
function displayQuestion() {
const currentQuestion = Questions[currentQuestionIndex];
const questionEl = document.querySelector(".title");
const answerContainer = document.querySelector(".options");
// 清空上一题的选项
answerContainer.innerHTML = "";
// 更新题目文本
questionEl.textContent = currentQuestion.question;
// 渲染新选项并绑定一次性事件
currentQuestion.options.forEach((option, index) => {
const answer = document.createElement("div");
answer.textContent = option;
answer.classList.add("answer");
answer.dataset.index = index; // 可选:便于后续扩展(如高亮正确答案)
answer.addEventListener("click", () => checkAnswer(option));
answerContainer.appendChild(answer);
});
}✅ checkAnswer() 补充逻辑(增强反馈与防误触)
function checkAnswer(selectedOption) {
const currentQuestion = Questions[currentQuestionIndex];
const nextBtn = document.querySelector(".next");
if (selectedOption === currentQuestion.correctAnswer) {
score++;
}
// 启用「下一题」按钮(假设初始为 disabled 或隐藏)
nextBtn.classList.remove("disabled");
nextBtn.classList.add("open");
// 可选:临时视觉反馈(如高亮正确/错误选项)
const answers = document.querySelectorAll(".answer");
answers.forEach(el => {
el.style.pointerEvents = "none"; // 禁用重复点击
if (el.textContent === currentQuestion.correctAnswer) {
el.style.backgroundColor = "#d4edda";
} else if (el.textContent === selectedOption && selectedOption !== currentQuestion.correctAnswer) {
el.style.backgroundColor = "#f8d7da";
}
});
}⚠️ 注意事项与最佳实践
- DOM 元素需提前存在:确保 HTML 中已定义 .title、.options、.next 等选择器对应元素,否则 querySelector 返回 null,引发运行时错误。
- 初始化校验:首次加载时调用 displayQuestion(),并禁用「下一题」按钮(直到用户作答)。
- 索引边界处理:务必在递增前判断 currentQuestionIndex
- 状态重置支持:如需「重新开始」功能,应重置 currentQuestionIndex = 0 和 score = 0,并再次调用 displayQuestion()。
- 可访问性建议:为按钮添加 aria-label="Next question",选项使用










