Search code examples
javascriptgoogle-chromereview

I cannot leave from while loop of JavaScript


I am refactoring my code below, before refactoring the code works. I am searching for my mistake with console.log, but I could not find it. Why I cannot leave the loop?

Here is the code

const questions = [
        ["ゲーム市場最も売れたゲームは?"],
    ]
    
    const answers = [["SFC", "PS2", "NintendoDS","NintendoSwitch"],]
    
    const correct = [["NintendoDS"]]
    
    let $button = document.getElementsByTagName("Button")
    const setupQuiz = () =>{
        document.getElementById("js-question").textContent = questions[0][0]
    
        let buttonIndex = 0
        let buttonLength = $button.length
        while (buttonIndex < buttonLength){
            $button[buttonIndex].textContent = answers[0][buttonIndex]
            buttonIndex++
        }
    }
    
    setupQuiz()
    
    const clickHandler = (e) => {
        if (correct[0][0] === e.target.textContent){
            window.alert('Correct!')
        } else {
            window.alert('Wrong...')
        }
    }
    
    let buttonIndex = 0
    const buttonLength = $button.length
    console.log(buttonLength)
    
    //The loop is here...
    while (buttonIndex < buttonLength){
        $button[buttonIndex].addEventListener('click', (e) => {
            clickHandler(e)
            buttonIndex++
            console.log(buttonIndex)
        })
    }
    
    //I wanna refactoring below
    // $button[0].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })
    //
    // $button[1].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })
    //
    // $button[2].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })
    //
    // $button[3].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })

Solution

  • It's because of this code.

    while (buttonIndex < buttonLength){
            $button[buttonIndex].addEventListener('click', (e) => {
                clickHandler(e)
                buttonIndex++
                console.log(buttonIndex)
            })
        }
    

    It will update the buttonIndex when user will click on the button that's why it never changes. You need to move this outside the Event Listener.

    I changed this code to

    while (buttonIndex < buttonLength) {
      $button[buttonIndex].addEventListener('click', (e) => {
        clickHandler(e)
        console.log(buttonIndex)
      })
      buttonIndex++
    }
    

    now it's working fine as expected


    Full Code

    const questions = [
      ["ゲーム市場最も売れたゲームは?"],
    ]
    
    const answers = [
      ["SFC", "PS2", "NintendoDS", "NintendoSwitch"],
    ]
    
    const correct = [
      ["NintendoDS"]
    ]
    
    let $button = document.getElementsByTagName("Button")
    const setupQuiz = () => {
      document.getElementById("js-question").textContent = questions[0][0]
    
      let buttonIndex = 0
      let buttonLength = $button.length
      while (buttonIndex < buttonLength) {
        $button[buttonIndex].textContent = answers[0][buttonIndex]
        buttonIndex++
        console.log("here", buttonIndex)
      }
    }
    
    setupQuiz()
    
    const clickHandler = (e) => {
      if (correct[0][0] === e.target.textContent) {
        window.alert('Correct!')
      } else {
        window.alert('Wrong...')
      }
    }
    
    let buttonIndex = 0
    const buttonLength = $button.length
    console.log("length", buttonLength)
    
    //The loop is here...
    while (buttonIndex < buttonLength) {
      $button[buttonIndex].addEventListener('click', (e) => {
        clickHandler(e)
        console.log(buttonIndex)
      })
      buttonIndex++
    }
    console.log("stopped")
    
    //I wanna refactoring below
    // $button[0].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })
    //
    // $button[1].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })
    //
    // $button[2].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })
    //
    // $button[3].addEventListener('click', (e) => {
    //     clickHandler(e)
    // })
    <button id="js-question">Button</button>