I am a complete beginner in JS. I am trying to make a quiz using JS but constantly getting this error. Can anyone help, please?
This is my HTML:
<body>
<div id="quiz"></div>
<button id="submit">Get Results</button>
<div id="results"></div>
</body>
Here is my JS code:
var myQuestions = [
{
question: "What is 10/2?",
answers: {
a: '3',
b: '5',
c: '115'
},
correctAnswer: 'b'
},
{
question: "What is 30/3?",
answers: {
a: '3',
b: '5',
c: '10'
},
correctAnswer: 'c'
}
];
var quizContainer = document.getElementById("quiz");
var resultsContainer = document.getElementById("results");
var submitButton = document.getElementById("submit");
function generateQuiz(questions, quizContainer, resultsContainer, submitButton){
function showQuestions(questions, quizContainer){
// we'll need a place to store the output and the answer choices
var output = [];
var answers;
// for each question...
for(var i=0; i<questions.length; i++){
// first reset the list of answers
answers = [];
// for each available answer to this question...
for(letter in questions[i].answers){
// ...add an html radio button
answers.push(
'<label>'
+ '<input type="radio" name="question'+i+'" value="'+letter+'">'
+ letter + ': '
+ questions[i].answers[letter]
+ '</label>'
);
}
// add this question and its answers to the output
output.push(
'<div class="question">' + questions[i].question + '</div>'
+ '<div class="answers">' + answers.join('') + '</div>'
);
}
// finally combine our output list into one string of html and put it on the page
quizContainer.innerHTML = output.join('');
}
function showResults(questions, quizContainer, resultsContainer){
}
// show the questions
showQuestions(questions, quizContainer);
// when user clicks submit, show results
submitButton.onclick = function(){
showResults(questions, quizContainer, resultsContainer);
}
}
generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);
I am getting this error in my console. It's showing that it can't set innerHTML
property of a null element even though I have already defined it.
This is the line where I think the problem is:
quizContainer.innerHTML = output.join('');
Probably the reason is that you wrote your js before your HTML. Try to put your script below your body part. You need to have your div rendered first and then your script will find it on your page by id.
Write your JS code in window.onload
. It will run only when the DOM elements are ready. Use the following code snippet:
window.onload = function() {
// quiz code goes here...
};
When the browser loads the page and comes across a <script>
tag, it executes the script at this moment and does not continue building the DOM. Therefore, the elements you are referencing in the script do not exist at this point.
The best way would be to make the script execute the generateQuiz
explicitly in window.onload
and to hide the variables. This separates loading and execution of the desired function in the script and gives you explicit control when the callback (generation of quiz) is actually executed.
window.onload = function() {
const quizContainer = document.getElementById("quiz");
const resultsContainer = document.getElementById("results");
const submitButton = document.getElementById("submit");
generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);
}
Another way is to use defer
in order to run the script after the DOM is fully built:
<!doctype html>
<html>
<head>
<script defer src="script.js"></script>
</head>
<body>
<div id="quiz"></div>
<button id="submit">Get Results</button>
<div id="results"></div>
</body>
</html>
Or just by placing the script below the elements that are referred:
<!doctype html>
<html>
<body>
<div id="quiz"></div>
<button id="submit">Get Results</button>
<div id="results"></div>
<script src="script.js"></script>
</body>
</html>
I added js code inside showResults function so now you will get results.
var myQuestions = [ { question: "What is 10/2?", answers: { a: '3', b: '5', c: '115' }, correctAnswer: 'b' }, { question: "What is 30/3?", answers: { a: '3', b: '5', c: '10' }, correctAnswer: 'c' } ]; var quizContainer = document.getElementById("quiz"); var resultsContainer = document.getElementById("results"); var submitButton = document.getElementById("submit"); function generateQuiz(questions, quizContainer, resultsContainer, submitButton){ function showQuestions(questions, quizContainer){ // we'll need a place to store the output and the answer choices var output = []; var answers; // for each question... for(var i=0; i<questions.length; i++){ // first reset the list of answers answers = []; // for each available answer to this question... for(letter in questions[i].answers){ //...add an html radio button answers.push( '<label>' + '<input type="radio" name="question'+i+'" value="'+letter+'"> ' + letter + ': ' + questions[i].answers[letter] + '</label>' ); } // add this question and its answers to the output output.push( '<div class="question">' + questions[i].question + '</div>' + '<div class="answers">' + answers.join('') + '</div>' ); } // finally combine our output list into one string of html and put it on the page quizContainer.innerHTML = output.join(''); } function showResults(questions, quizContainer, resultsContainer){ var array = []; var checkboxes = document.querySelectorAll('#quiz input[type=radio]:checked'); for (var i = 0; i < checkboxes.length; i++) { array.push(checkboxes[i].value) } resultsContainer.innerHTML = array; } // show the questions showQuestions(questions, quizContainer); // when user clicks submit, show results submitButton.onclick = function(){ showResults(questions, quizContainer, resultsContainer); } } generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);
.answers{ margin-top: 2px; margin-bottom: 10px; } label{ margin-right:15px; } #results{ font-weight: 900; font-size: 17px; margin-left: 15px; color: green; display: inline-block; }
<div id="quiz"></div> <button type="button" id="submit">Get Results</button> <div id="results"></div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.