I'm having an issue were the event listener is not being removed, each time the gameLoop func is called again its doing eveything 2x, 4x, ect.. every time the game loop rolls around.
function gameLoop(data) {
let currentQuestion = newQuestion(data); // randomizes the question
displayAnswers.forEach(element => { // removes the added classes to show if the answer is right or wrong
element.classList.remove('correct');
element.classList.remove('incorrect');
element.removeEventListener('click', handleAnswerClick); // remove the event listener IS NOT WORKING
});
renderUi(currentQuestion); //loads Q/A to screen
displayAnswers.forEach(element => {
element.addEventListener('click', handleAnswerClick);
});
function handleAnswerClick(event) {
checkAnswer(event, currentQuestion, data);
}
}
https://drive.google.com/drive/folders/1xOrqXAdbzW0Xsr1nplK0hzcGJQrLbPog?usp=sharing - here is the code with a video of the bug in action
You defined handleAnswerClick
in the local scope of gameLoop
. The reference to the function is not available when a second call is made to gameLoop
. Since handleAnswerClick
is defined with the function
statement, it is accessible directly from the start of the gameLoop
function, and it is then incorrectly passed to removeEventListener.
The issue happens somewhat like this:
gameLoop()[run 1]:
- function handleAnswerClick(...){...}//Even if defined at the end,
//functions defined with the function keyword
//are available inside the scope they were defined in [here:gameLoop() local scope] at all times
- addEventListener(...)
gameLoop()[run 2]:
- removeEventListener(...)//This is where the issue is.
//In the second call, a new handleAnswerClick is defined into the local scope,
//this is a different local scope than the first one.
//now, the new handleAnswerClick, which is different than the old handleAnswerClick,
//is passed to removeEventListener. removeEventListener does not throw an error if a
//unregistered function is passed, it ignores it instead. This applies to the new function,
//as the old function is the one that was registered, and the new function is different from it
- ...
gameLoop()[run X]:
- ...
your new function should look like this:
function gameLoop(data) {
let currentQuestion = newQuestion(data); // randomizes the question
displayAnswers.forEach(element => { // removes the added classes to show if the answer is right or wrong
element.classList.remove('correct');
element.classList.remove('incorrect');
element.removeEventListener('click', window.lastClickHandlerFunction); //will be undefined on first call, later it is the correct function
});
renderUi(currentQuestion); //loads Q/A to screen
displayAnswers.forEach(element => {
element.addEventListener('click', handleAnswerClick);
});
window.lastClickHandlerFunction=handleAnswerClick;//Store a reference to the registered function
function handleAnswerClick(event) {
checkAnswer(event, currentQuestion, data);
}
}