JavaScript实现答题测验移除DOM容器导致后续选项无法渲染问题
问题原因
你用.remove()直接删掉了HTML里写死的固定父容器:这个方法会把元素从DOM树里彻底移除,不是只清空内容,后面再调用appendChild往这些容器里塞新内容的时候,节点已经不存在了,自然渲染失败。
除此之外你的代码还有几个会影响功能的小问题:
- 同时用了
q和currentQuestion两个变量存当前题号,两个变量分别自增,会导致题目、选项、正确答案匹配错位 - 选项列表是页面加载时就创建好的,切换题目时没清空旧选项,后面的题目选项会堆在一起
- 选项点击事件绑在父容器上,点到容器空白区域也会触发判题
- 2秒等待期间没有禁止重复点击,用户快速点选项会重复触发判题逻辑,导致题目跳转过快
修复方案
核心原则:固定布局的父容器永远不要删,每次切换题目只清空容器内部的动态生成内容。
- 保留HTML里预先写好的
.questions/.choices/.answer三个固定div,绝对不要对这三个节点调用.remove() - 清空内容时直接把容器的
innerHTML设为空字符串,只删掉内部动态生成的li、p标签即可 - 删掉重复的题号变量,全程只用一个变量控制当前题目位置
- 给点击事件加判断,只有点到选项li的时候才触发判题,等待期间暂时禁止选项点击
修正后的核心代码
首先改清空内容的两个函数,别删父容器:
// 清空上一题选项 function removeChoices () { choicesListEl.innerHTML = ''; } // 清空正确/错误提示 function removeAnswer () { answerEl.innerHTML = ''; }
然后统一题号变量,修正题目渲染逻辑,把原来的var q=0删掉,只用currentQuestion:
var currentQuestion = 0; function displayQuestions () { // 渲染新题目前先清掉上一题的残留内容 removeChoices(); removeAnswer(); questionsEl.textContent = quizQuestions[currentQuestion].question; displayChoices(); } function displayChoices () { for (let i = 0; i < quizQuestions[currentQuestion].choices.length; i++){ var li = document.createElement("li"); li.textContent = quizQuestions[currentQuestion].choices[i]; choicesListEl.appendChild(li); } }
修正判题逻辑,加点击校验和防重复点击:
function displayAnswer (event) { // 点的不是选项li就直接返回,不触发判题 if(event.target.tagName !== 'LI') return; // 2秒等待期间禁止重复点击选项 choicesListEl.style.pointerEvents = 'none'; var p = document.createElement("p"); if (quizQuestions[currentQuestion].answer === event.target.textContent) { p.textContent = "Correct" } else { p.textContent = "Incorrect"; startTime -= 8; } answerEl.appendChild(p); setTimeout (function () { currentQuestion++; // 所有题目答完直接结束测验 if(currentQuestion >= quizQuestions.length) { endQuiz(); return; } displayQuestions(); // 新题目渲染完成后恢复点击 choicesListEl.style.pointerEvents = 'auto'; }, 2000); }
最后修正初始化部分的代码,去掉给choicesListEl重复加class的逻辑(外层div已经有choices类了,ul不需要再加同名类,避免CSS样式冲突):
var choicesListEl = document.createElement("ul"); choicesEl.appendChild(choicesListEl);
顺手提一句:你写的HTML有标签嵌套错误,
.intro-text的闭合标签放错位置了,跑到</main>外面了,记得调整下标签顺序,不然会有样式问题。
内容的提问来源于stack exchange,提问作者damarts
相关产品推荐
相关产品推荐

