开发JS Quiz应用:loadQuiz()中question变量为null的原因
问题:Quiz应用中loadQuiz()函数的question变量始终为null的原因及解决办法
问题描述
开发简易Quiz应用时,loadQuiz()函数中的question变量始终返回null,HTML中已正确设置id="question",尝试将quizdata数组的题目赋值给该元素文本内容时,控制台报错:
Uncaught TypeError: question is null
核心原因
你的JS脚本在DOM元素加载完成前就执行了。HTML里的<script src="index.js"></script>放在了<body>标签的最开头,此时浏览器还未解析后面的<h2 id="question">等DOM元素,所以document.getElementById('question')无法找到目标元素,返回null。
解决办法
有两种可行的修复方式:
1. 将JS脚本移到</body>标签前
把脚本放在页面最后,确保所有DOM元素都已被浏览器解析完成后再执行JS代码。修改后的HTML结构如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Quiz</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous"> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <div class="row justify-content-center"> <div class="col-md-7 "> <h1 class="text-center">JS Quiz</h1> <hr class="rounded"> <div id="quizdiv"> <h2 id="question"> Question </h2> <hr class="dashed"> <li> <input type="radio" name="answer" id="a" class="answer"> <label for="a" id="a_value">option a</label> </li> <li> <input type="radio" name="answer" id="b" class="answer"> <label for="b" id="b_value">option b</label> </li> <li> <input type="radio" name="answer" id="c" class="answer"> <label for="c" id="c_value">option c</label> </li> <li> <input type="radio" name="answer" id="d" class="answer"> <label for="d" id="d_value">option d</label> </li> <button class="btn btn-primary" id="submit">SUBMIT</button> </div> </div> </div> </div> <!-- 把脚本移到这里 --> <script src="index.js"></script> </body> </html>
2. 使用DOMContentLoaded事件包裹JS代码
如果不想移动脚本位置,可以用DOMContentLoaded事件监听,让JS代码等到DOM加载完成后再执行。修改后的JS代码如下:
document.addEventListener('DOMContentLoaded', function() { var quizdata= [ { question:"Which framework is related to JS ?", a:'.net', b:'Flask', c:'React', d:'Django', correct: 'c' }, { question:"Which is not a programming language ?", a:'HTML', b:'Python', c:'Java', d:'JavaScript', correct: 'a' }, { question:"Which is not a framework ?", a:'React', b:'JavaScript', c:'Angular', d:'Django', correct: 'b' }, { question:"CSS stands for - ", a:'Cascading Style State', b:'Cascading Style Sheet', c:'Cascading Sheet of Style', d:'None of the above', correct: 'b' } ] var quiz = document.getElementById('quiz') var answer = document.querySelectorAll('.answer') var question = document.getElementById('question') var option_a=document.getElementById ('a_value') var option_b=document.getElementById ('b_value') var option_c=document.getElementById ('c_value') var option_d=document.getElementById ('d_value') var submitbtn=document.getElementById('submit') var currentQuestion=0 var quizScore=0 loadQuiz() console.log(option_a) function loadQuiz(){ deselect() question.innerHTML= quizdata[currentQuestion].question option_a.innerText= quizdata[currentQuestion].a option_b.innerText= quizdata[currentQuestion].b option_c.innerText= quizdata[currentQuestion].c option_d.innerText= quizdata[currentQuestion].d } function deselect() { answer.forEach(answer=>answer.checked=false) } submitbtn.addEventListener('click', ()=>{ var selectedOption answer.forEach(answer=>{ if(answer.checked) { selectedOption=answer.id } }) if(selectedOption==quizdata[currentQuestion].correct) { quizScore+=1 } currentQuestion+=1 if(currentQuestion==quizdata.length) { // 注意这里要改成反引号和${}模板字符串 document.getElementById('quizdiv').innerHTML=`<h1>You have answered ${quizScore} correctly out of ${quizdata.length}</h1>` } else { loadQuiz() } }) });
额外修复点
提交结果的模板字符串有误:你用了单引号和$(),这无法解析变量,需要改成反引号包裹,并用${变量名}的格式,比如:
document.getElementById('quizdiv').innerHTML=`<h1>You have answered ${quizScore} correctly out of ${quizdata.length}</h1>`
内容的提问来源于stack exchange,提问作者Prophet_17
相关产品推荐
相关产品推荐

