skip to Main Content

This is supposed to be a trivia question website, which reflects whether the user’s answer is incorrect or not after clicking buttons. My issue arises with the ‘for’ loop related to the incorrect answers.

            
            document.addEventListener('DOMContentLoaded', function(){
               


                // Part 1
                event.preventDefault();

                let correctans = document.getElementById('correct1');

                correctans.addEventListener('click', function(){
                correctans.style.backgroundColor = 'green';
                document.querySelector('#response1').innerHTML = 'Correct!';
                });



                let incorrectans = document.querySelectorAll('.incorrect')
                /*
                querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements
                that match the specified group.
                It's possible to loop over the items in a NodeList using a for loop
                */
                let i = 0;
                for (i = 0; i < incorrectans.length; i++)
                {
                    incorrectans[i].addEventListener('click', function(){
                    incorrectans[i].style.backgroundColor = 'red';
                    document.querySelector('#response1').innerHTML = 'Incorrect.';
                    console.log(i);

                    })

                }

Below is my HTML code


            <div class="section">
                <h2>Part 1: Multiple Choice </h2>
                <p id="response1"> </p>
                <hr>
                <!-- TODO: Add multiple choice question here -->
                <h3>What is the largest rodent on Earth?</h3>
                <button type="button" value="answer" class="incorrect">Beaver</button>
                <button type="button" value="answer" class="incorrect">Squirrel</button>
                <button type="button" value="correctanswer" id="correct1">Capybara</button>
                <button type="button" value="answer" class="incorrect">Rat</button>

           </div>

When I assign 0 to the variable ‘i’ before using it in the ‘for’ loop, debugging with console.log() shows that ‘i’ does not reflect the values that I assigned it, nor the values after it was incremented.

The ‘for’ loop only works when the ‘i’ is declared in the loop itself. Why is that?

And in the same vein, another question I have is that, does addEventListener('DOMContentLoaded') always have to be used in JavaScript?

3

Answers


  1. For loop has three parts namely initialization, condition, increment. Initialization is optional so you can leave it blank. But if you put i=0 in initialization part a new variable will be created for the scope of that loop. If you want to use a value from outside, you have to leave the initialization part blank or simply put the variable name there no value is to be given. And you don’t have to use addEventListener('DOMContentLoaded') at all. You just have to either put your script at the end of body or if you put it somewhere else add a defer attribute to your script tag like <script src="main.js" defer > </script>. defer makes the script run at last when whole document is loaded.

    const correctans = document.getElementById('correct1');
    const response = document.querySelector('#response1');
    const incorrectans = document.querySelectorAll('.incorrect');
    
    correctans.addEventListener('click', function(e) {
      e.target.style.backgroundColor = 'green';
      response.innerHTML = 'Correct!';
    });
    
    let i = 0;
    for (; i < incorrectans.length; i++) {
      console.log(i);
      incorrectans[i].addEventListener('click', function(e) {
        e.target.style.backgroundColor = 'red';
        response.innerHTML = 'Incorrect.';
      });
    }
    <div class="section">
      <h2>Part 1: Multiple Choice </h2>
      <p id="response1"> </p>
      <hr>
      <!-- TODO: Add multiple choice question here -->
      <h3>What is the largest rodent on Earth?</h3>
      <button type="button" value="answer" class="incorrect">Beaver</button>
      <button type="button" value="answer" class="incorrect">Squirrel</button>
      <button type="button" value="correctanswer" id="correct1">Capybara</button>
      <button type="button" value="answer" class="incorrect">Rat</button>
    
    </div>
    Login or Signup to reply.
  2. Event listener works asynchronously. And if you declare a variable outside of loop all events were not fired yet but loop has run. After loop has been run the final value we will get will be i = 3 (as for loop does increment once after ending condition has been met).

    Now when we click on button and event listener fires. it reads value of i as 3 but incorrectans array contains only 3 value with index 0,1,2. Hence the error.

    In case when declare inside the loop, the event listener stores current value of i. Thus running properly.

    EXTRA :- To understand this properly what you can do is run the loop and then give i a different value outside of the loop like 1. But in that case if will not throw error but it will always red the option with index 1 regardless of option you choose.

    Best would be to declare let inside loop. Alternatively you can also use this

    let i = 0;
    for (i = 0; i < incorrectans.length; i++)
        {
            let j = i
            incorrectans[j].addEventListener('click', function(){
                    incorrectans[j].style.backgroundColor = 'red';
                    document.querySelector('#response1').innerHTML = 'Incorrect.';
                    console.log(j);
    
                     })
    
    
        }
    

    Also no you don’t have to always use addEventListener(‘DOMContentLoaded’) in your code. But in your above code where you using event listener for dom elements. It is good to wait for them to load. Their are alternative like defer which indicate that this script is executed after the document has been parsed. You can use defer using

    <script src="code.js" defer></script>
    
    Login or Signup to reply.
  3. i get thet the i isn t getting the decimal values,so after checking ur code ,i found the function part:

     incorrectans[i].addEventListener('click', ****function(){
                        incorrectans[i].style.backgroundColor = 'red';
                        document.querySelector('#response1').innerHTML = 'Incorrect.';
                        console.log(i);
    
                        }****)
    

    -u opened a function without passing the the i variable,thet s why u are not seeing the expected values, so if u want to correct this u need to put the console.log(i); out of the function brackets or pass the i variable to ur function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search