Я не могу выйти из цикла while в JavaScript

#javascript #google-chrome #review

#javascript #google-chrome #обзор

Вопрос:

Я рефакторингую свой код ниже, прежде чем рефакторинг кода сработает. Я ищу свою ошибку с console.log, но я не смог ее найти. Почему я не могу выйти из цикла?

Вот код

 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)
    // })
  

Комментарии:

1. buttonIndex я думаю, что он должен быть вне addEventListener вызова

Ответ №1:

Ваш цикл while добавляет прослушиватель событий к кнопке.

Затем он добавляет еще один.

Затем он добавляет еще один.

И так далее, бесконечно.

Условие, которое вы тестируете ( buttonIndex < buttonLength ), никогда не меняется.

Это может измениться, если когда-либо будет вызван прослушиватель событий, но если в нем должно быть зарегистрировано событие click, обработчик событий не будет вызван, потому что основной цикл событий слишком занят, выполняя ваш просмотр while, чтобы когда-либо проверять.

Ответ №2:

Это из-за этого кода.

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

Он обновит buttonIndex, когда пользователь нажмет на кнопку, поэтому он никогда не меняется. Вам нужно переместить это за пределы прослушивателя событий.

Я изменил этот код на

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

теперь он работает нормально, как и ожидалось


Полный код

 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>  

Ответ №3:

Это потому, что функция addeventlistener не выполняется в цикле (выполняется только при нажатии на кнопку). Таким образом, buttonIndex не применяется.

Вы должны разместить его также за пределами функции addeventlistener.