JavaScript答题系统正确答案识别异常问题求助
解决随机选项后的正确答案识别问题
问题根源
你现在的核心问题是:选项随机打乱后,页面上的.choice-text元素的data-number还是固定的1-4,但这些编号对应的选项内容已经和题目对象里的原始choice1-choice4不匹配了。比如某题的answer是4(对应原始choice4的内容),打乱后choice4的内容可能出现在data-number=1的位置,此时用户点击这个选项,代码会拿1和4对比,错误判定为不正确。
修复方案(两种可选)
方案一:打乱选项时同步更新data-number
修改getNewQuestion函数里的选项处理逻辑,把选项文本和对应的原始编号绑定成对象,打乱后同步更新每个选项的data-number,让编号始终对应原始选项的编号:
//Get new question and increment the question counter getNewQuestion = () => { if (availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS) { localStorage.setItem('mostRecentScore', score); return window.location.assign('index.html') /* Take player to end game*/ } questionCounter++; const questionsIndex = Math.floor(Math.random() * availableQuestions.length); currentQuestion = availableQuestions[questionsIndex]; question.innerText = currentQuestion.question; // 把选项文本和对应的原始编号组合成对象数组 const answerChoices = [ { text: currentQuestion.choice1, number: 1 }, { text: currentQuestion.choice2, number: 2 }, { text: currentQuestion.choice3, number: 3 }, { text: currentQuestion.choice4, number: 4 }, ]; //Call randomize choices function shuffle(answerChoices); //Display randomized choices 并同步更新data-number choices.forEach((choice, index) => { choice.innerHTML = answerChoices[index].text; choice.dataset.number = answerChoices[index].number; // 关键:更新data-number }); availableQuestions.splice(questionsIndex, 1); acceptingAnswers = true; }
这样修改后,selectedAnswer == currentQuestion.answer的判断逻辑就能正常工作,因为每个选项的data-number现在和它对应的原始选项编号一致。
方案二:直接对比选项文本(更简洁)
不需要修改data-number,而是在点击时直接对比选中的文本和当前题目的正确选项文本:
//Check answer if correct choices.forEach(choice => { choice.addEventListener('click', e => { if (!acceptingAnswers) return acceptingAnswers = false; const selectedChoice = e.target; // 获取当前题目的正确选项文本 const correctText = currentQuestion['choice' + currentQuestion.answer]; // 对比选中的文本(trim去除可能的空格) let classToApply = selectedChoice.textContent.trim() === correctText ? 'correct' : 'incorrect'; if (classToApply === 'correct') { incrementScore(SCORE_POINTS); } selectedChoice.parentElement.classList.add(classToApply); setTimeout(() => { selectedChoice.parentElement.classList.remove(classToApply); getNewQuestion(); }, 1000); }) })
这种方法更直接,不需要维护编号对应关系,适合你的题目选项文本唯一的场景。
完整修复后的代码示例(以方案二为例)
const question = document.querySelector('#question'); const choices = Array.from(document.querySelectorAll('.choice-text')); const progressText = document.querySelector('#progressText'); const scoreText = document.querySelector('#score'); const progressBarFull = document.querySelector('#progressBarFull'); const SCORE_POINTS = 10; const MAX_QUESTIONS = 3; let currentQuestion = {}; let acceptingAnswers = true; let score = 0; let questionCounter = 0; let availableQuestions = []; /* Object containing the questions of the quiz game. */ let questions = [{ question: '根据罗马神话,罗慕路斯和雷穆斯的父亲是谁?', choice1: '一只狼', choice2: '努米托国王', choice3: '朱庇特', choice4: '玛尔斯', answer: 4, }, { question: '第一条罗马道路是哪一条?', choice1: '埃格纳提亚大道', choice2: '瓦莱里亚大道', choice3: '阿皮亚大道', choice4: '弗拉米尼亚大道', answer: 3, }, { question: '以下哪一位没有击败本都的米特拉达梯六世?', choice1: '卢库鲁斯', choice2: '马略', choice3: '庞培', choice4: '苏拉', answer: 2, } ] // Start game by setting default hud values function startGame() { questionCounter = 0; score = 0; availableQuestions = [...questions]; /* Spread operator */ getNewQuestion() } //Randomize question choices shuffle = array => { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } //Get new question and increment the question counter getNewQuestion = () => { if (availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS) { localStorage.setItem('mostRecentScore', score); return window.location.assign('index.html') /* Take player to end game*/ } questionCounter++; const questionsIndex = Math.floor(Math.random() * availableQuestions.length); currentQuestion = availableQuestions[questionsIndex]; question.innerText = currentQuestion.question; //Locate choices const answerChoices = [ currentQuestion.choice1, currentQuestion.choice2, currentQuestion.choice3, currentQuestion.choice4, ]; //Call randomize choices function shuffle(answerChoices); //Display randomized choices choices.forEach((choice, index) => { choice.innerHTML = answerChoices[index]; }); availableQuestions.splice(questionsIndex, 1); acceptingAnswers = true; } //Check answer if correct choices.forEach(choice => { choice.addEventListener('click', e => { if (!acceptingAnswers) return acceptingAnswers = false; const selectedChoice = e.target; // 获取正确选项文本 const correctText = currentQuestion['choice' + currentQuestion.answer]; // 对比文本判断对错 let classToApply = selectedChoice.textContent.trim() === correctText ? 'correct' : 'incorrect'; if (classToApply === 'correct') { incrementScore(SCORE_POINTS); } selectedChoice.parentElement.classList.add(classToApply); setTimeout(() => { selectedChoice.parentElement.classList.remove(classToApply); getNewQuestion(); }, 1000); }) }) incrementScore = num => { score += num; scoreText.innerText = score; } startGame()
CSS和HTML部分保持原代码即可。
内容的提问来源于stack exchange,提问作者KRANKENdude
相关产品推荐
相关产品推荐

