简体   繁体   中英

Having trouble in building my first JS quiz

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM