I’m trying to remove click events from a list of id’s after adding them with an IIFE like this
function setupPlayer(player){ var squareState = {}; for (i = 0; i < allSquares.length; i++) { if(allSquares[i].innerHTML === "") { // set up a click event for each square document.getElementById(allSquares[i].getAttribute('id')).addEventListener('click', (clickSquare)(i)); } } }
The clickSquare function returns
function clickSquare(i){ var num = i; return function() { document.getElementById(allSquares[num].getAttribute('id')).innerHTML=player; } }
Then I try to remove them with
function removeClickEvents(){ for (let i = 0; i < allSquares.length; i++) { document.getElementById(allSquares[i].getAttribute('id')).removeEventListener('click', clickSquare); } }
I’ve tried naming the returned anonymous function and using removeEventListener
on that to no avail.
Advertisement
Answer
To remove event listener from a DOM element you need to pass the same function you used while adding event listener, as the parameter.
In javascript when you create an object it creates a new instance of that object class, so it won’t be equal to another object even if it is created with same parameters
Example:
{} != {} // returns true [] != [] // returns true
Same goes with function, whenever you write function (){}
it creates a new instance of Function
class.
Example:
function a() { return function b() {} } a() != a() // returns true
Solution:
So for you to be able to remove the event listeners, you will have to store the functions you have passed to addEventListener
var listeners = []; function setupPlayer(player) { var squareState = {}; for (i = 0; i < allSquares.length; i++) { if(allSquares[i].innerHTML === "") { listeners[i] = clickSquare(i); document.getElementById(allSquares[i].getAttribute('id')).addEventListener('click', listeners[i]); } } } function clickSquare(i) { var num = i; return function() { document.getElementById(allSquares[num].getAttribute('id')).innerHTML=player; } } function removeClickEvents() { for (let i = 0; i < allSquares.length; i++) { if(listeners[i]) { document.getElementById(allSquares[i].getAttribute('id')).removeEventListener('click', listeners[i]); } } }
From your code where you are using
document.getElementById(allSquares[i].getAttribute('id'))
I am assuming that allSquares[i]
is a DOM element already, your code can be more simplified
var listeners = []; function setupPlayer(player) { var squareState = {}; for (i = 0; i < allSquares.length; i++) { if(allSquares[i].innerHTML === "") { listeners[i] = clickSquare(i); allSquares[i].addEventListener('click', listeners[i]); } } } function clickSquare(i) { var num = i; return function() { allSquares[num].innerHTML=player; } } function removeClickEvents() { for (let i = 0; i < allSquares.length; i++) { if(listeners[i]) { allSquares[i].removeEventListener('click', listeners[i]); } } }