Reputation: 170
I am having issues dynamically adding and removing eventListeners. I want to be able to add an event listener to all child nodes of an element. Then at a later time remove them, and add them back.
Note: I am aware of EventListener options.once however this doesn't exactly solve my case.
Here is some sample code of what I am trying to do:
var cont;
window.onload = function() {
cont = document.querySelector(".container");
[...cont.children].forEach(c => {
c.addEventListener("click", clicked.bind(c))
});
}
function clicked() {
console.log(`removing event listener from ${this}`);
this.removeEventListener("click", clicked); //Not actually removing - why?
}
Thanks everyone!
Upvotes: 2
Views: 733
Reputation: 370699
The problem is that .bind
creates a new function. The function passed to addEventListener
can only be removed if that exact same function is passed to removeEventListener
. A bound function is not the same as the original unbound function, so removeEventListener
won't work if you pass it the unbound function.
In your situation, one possibility would be to use a Map
indexed by the HTML elements, whose value is the bound listener for that element, so that they can then be removed later:
const listenerMap = new Map();
const cont = document.querySelector(".container");
[...cont.children].forEach(c => {
const listener = clicked.bind(c);
listenerMap.set(c, listener);
c.addEventListener("click", listener);
});
function clicked() {
console.log(`removing event listener from ${this}`);
this.removeEventListener("click", listenerMap.get(this));
}
<div class="container">
<div>one</div>
<div>two</div>
<div>three</div>
</div>
Upvotes: 2