测验题选项随机排序时重复显示问题的修复咨询
问题分析与修复方案
你的代码出现选项重复的核心原因有以下几点:
- 循环内重复洗牌:每次循环都重新洗牌答案数组,导致每次获取的都是洗牌后数组的第一个元素,而非遍历所有选项。
- 固定取索引0:每次循环都将
i重置为0,始终取数组第一个元素,自然会出现重复。 - 未清理旧内容:使用
innerHTML +=会保留之前的选项,可能导致跨问题的内容残留。
修复后的代码
首先,将洗牌函数提取到外部(避免重复定义):
function shuffle(array) { let currentIndex = array.length, randomIndex; while (currentIndex !== 0) { randomIndex = Math.floor(Math.random() * currentIndex); currentIndex--; [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]; } return array; }
然后修改showQuestion函数:
function showQuestion() { /* 显示题目 */ let headerTemplate = `<h2 class="title">%title%</h2>`; let title = headerTemplate.replace('%title%', questions[questionIndex].question); headerContainer.innerHTML = title; /* 显示选项 */ listContainer.innerHTML = ''; // 清空之前的选项 const originalAnswers = questions[questionIndex].answer; const shuffledAnswers = shuffle([...originalAnswers]); // 复制原数组并洗牌,避免修改原数据 const questionTemplate = `<li> <label> <input value="%number%" type="radio" class="answer" name="answer"> <span>%answer%</span> </label> </li>`; let answerNumber = 1; for (const answer of shuffledAnswers) { let answerText = questionTemplate.replace('%answer%', answer).replace("%number%", answerNumber); listContainer.innerHTML += answerText; answerNumber++; } }
关键修复点说明
- 提前洗牌一次:在循环前完成洗牌,确保后续遍历的是已经打乱顺序的完整选项数组。
- 复制原数组:使用
[...originalAnswers]创建原数组的副本,避免洗牌操作修改原始题目数据。 - 遍历洗牌后的数组:直接循环打乱后的数组,逐个添加每个选项,保证所有选项只出现一次。
- 清空容器:每次显示新题目时先清空选项容器,避免旧内容残留。
内容的提问来源于stack exchange,提问作者pozhara
相关产品推荐
相关产品推荐

