Blued00d
Blued00d

Reputation: 170

Adding and Removing Event Listeners Dynamically

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

Answers (1)

CertainPerformance
CertainPerformance

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

Related Questions