JS测验中传递第二个数组不修改原数组及修复功能异常
问题描述
我正在为一个JS测验开发第二种游戏模式,目前已有一套模式运行正常,另有一组问题存于另一个数组等待使用。但作为JS新手,我没法在不修改第一组数据的前提下,把第二个数组传入所有相关代码里。
我试过用if语句调用第二个数组,但后续函数全失效;也尝试把数组传入createQuestion函数,但控制台报错:
Uncaught TypeError: Cannot read properties of undefined (reading '1') at createQuestion (script.js:184:35) at HTMLButtonElement.nextQuestion (script.js:236:5)
相关代码片段
待传入的第二个问题数组
let quizData2 = [ { question: "assets/images/year/Brazil98-00.avif", answers: ["1997", "1999", "2002", "1995"], correct: "1999", }, { question: "assets/images/year/Denmark-92.webp", answers: ["1991", "1990", "1995", "1992"], correct: "1992", }, ];
游戏模式启动函数
document.getElementById('guess-shirt-start-btn').addEventListener('click', startGuessShirtTeam); document.getElementById('guess-year-start-btn').addEventListener('click', startGuessShirtYear); // 启动"猜球衣队伍"模式 function startGuessShirtTeam () { document.getElementById('game-choices-container').classList.add('hidden'); document.getElementById('question-container').classList.remove('hidden'); gameMode = 'shirt-quiz' modeOfGame(); console.log(gameMode) createQuestion(quizData1); displayNumberOfQuestions(); }; // 启动"猜球衣年份"模式 function startGuessShirtYear () { document.getElementById('game-choices-container').classList.add('hidden'); document.getElementById('question-container').classList.remove('hidden'); gameMode = 'shirt-year' modeOfGame(); console.log(gameMode) createQuestion(quizData2) displayNumberOfQuestions(); }
问题渲染函数
function createQuestion (questionArray) { displayQuestionTitle(); shirtImage.src = questionArray[questionNumber].question; questionArray[questionNumber].answers.forEach((o) => { document.getElementById('answer-button-1').innerText = questionArray[questionNumber].answers[0] document.getElementById('answer-button-2').innerText = questionArray[questionNumber].answers[1] document.getElementById('answer-button-3').innerText = questionArray[questionNumber].answers[2] document.getElementById('answer-button-4').innerText = questionArray[questionNumber].answers[3] }); document.getElementById('answer-button-1').addEventListener('click', checkAnswer); document.getElementById('answer-button-2').addEventListener('click', checkAnswer); document.getElementById('answer-button-3').addEventListener('click', checkAnswer); document.getElementById('answer-button-4').addEventListener('click', checkAnswer); };
下一题函数
function nextQuestion () { let allAnswers = document.querySelectorAll('.answer-btns'); allAnswers.forEach((o) => { o.classList.remove('disabled') }); if (questionNumber >= maxQuestions - 1) { displayQuizResult(); return; } questionNumber++; clearCorrectAnswer(); clearQuestionTitle(); createQuestion(); clearAnswers(); showCurrentQuestionNumber(); }
答案校验函数
function checkAnswer (e) { let userAnswer = e.target.textContent; if (userAnswer === questionArray[questionNumber].correct) { userScore++; finalScore++; e.target.classList.add("correct"); showUserScore(); } else { e.target.classList.add("incorrect"); let correct = document.getElementById('correct-answer'); let correctAnswer = document.createTextNode(`Sorry that's incorrect, the answer is ${questionArray[questionNumber].correct}`); correct.appendChild(correctAnswer); } let allAnswers = document.querySelectorAll('.answer-btns'); allAnswers.forEach((o) => { o.classList.add('disabled') }); };
核心问题分析
nextQuestion调用createQuestion()未传数组:导致createQuestion内questionArray为undefined,触发报错。checkAnswer引用未定义的questionArray:该变量仅在createQuestion的参数中存在,全局无定义,导致校验逻辑失效。createQuestion内的forEach冗余:循环答案数组却重复赋值相同内容,完全没必要。- 重复绑定点击事件:每次创建问题都给按钮绑定一次
checkAnswer,多次点击会触发多次逻辑,造成混乱。
修复方案
步骤1:全局存储当前使用的问题数组
定义全局变量存储当前激活的问题数组,启动模式时赋值:
// 全局变量 let currentQuizData; let questionNumber = 0; function startGuessShirtTeam () { document.getElementById('game-choices-container').classList.add('hidden'); document.getElementById('question-container').classList.remove('hidden'); gameMode = 'shirt-quiz' modeOfGame(); console.log(gameMode) questionNumber = 0; // 重置问题编号 currentQuizData = quizData1; createQuestion(); displayNumberOfQuestions(); }; function startGuessShirtYear () { document.getElementById('game-choices-container').classList.add('hidden'); document.getElementById('question-container').classList.remove('hidden'); gameMode = 'shirt-year' modeOfGame(); console.log(gameMode) questionNumber = 0; // 重置问题编号 currentQuizData = quizData2; createQuestion(); displayNumberOfQuestions(); }
步骤2:修改createQuestion函数
移除冗余循环,使用全局数组,并且将事件绑定移到初始化阶段:
// 初始化时仅绑定一次点击事件,避免重复绑定 document.getElementById('answer-button-1').addEventListener('click', checkAnswer); document.getElementById('answer-button-2').addEventListener('click', checkAnswer); document.getElementById('answer-button-3').addEventListener('click', checkAnswer); document.getElementById('answer-button-4').addEventListener('click', checkAnswer); function createQuestion () { displayQuestionTitle(); const currentQuestion = currentQuizData[questionNumber]; shirtImage.src = currentQuestion.question; // 直接赋值答案,无需循环 document.getElementById('answer-button-1').innerText = currentQuestion.answers[0]; document.getElementById('answer-button-2').innerText = currentQuestion.answers[1]; document.getElementById('answer-button-3').innerText = currentQuestion.answers[2]; document.getElementById('answer-button-4').innerText = currentQuestion.answers[3]; };
步骤3:修改nextQuestion函数
调用createQuestion时无需传参,同时用当前数组长度判断是否结束:
function nextQuestion () { let allAnswers = document.querySelectorAll('.answer-btns'); allAnswers.forEach((o) => { o.classList.remove('disabled') }); // 用当前数组长度判断是否是最后一题 if (questionNumber >= currentQuizData.length - 1) { displayQuizResult(); return; } questionNumber++; clearCorrectAnswer(); clearQuestionTitle(); createQuestion(); clearAnswers(); showCurrentQuestionNumber(); }
步骤4:修改checkAnswer函数
使用全局数组替代未定义的questionArray,并清空旧提示:
function checkAnswer (e) { let userAnswer = e.target.textContent; const currentQuestion = currentQuizData[questionNumber]; if (userAnswer === currentQuestion.correct) { userScore++; finalScore++; e.target.classList.add("correct"); showUserScore(); } else { e.target.classList.add("incorrect"); let correct = document.getElementById('correct-answer'); correct.innerHTML = ''; // 清空旧提示 let correctAnswer = document.createTextNode(`抱歉答错了,正确答案是 ${currentQuestion.correct}`); correct.appendChild(correctAnswer); } let allAnswers = document.querySelectorAll('.answer-btns'); allAnswers.forEach((o) => { o.classList.add('disabled') }); };
内容的提问来源于stack exchange,提问作者Phil Smith
相关产品推荐
相关产品推荐

