removeEventListener() and anonymous functions

A short guide on the correct usage of removeEventListener()

Lately, I was trying to remove an event listener previously added from an element and it came out to be a proper riddle! I spent a good half an hour in order to find a solution, therefore decided to write this article as a reminder for the future myself and for my colleagues which might face the same case.

Stop listening to unnecessary noises!

The EventTarget.removeEventListener() method removes from the EventTarget an event listener previously registered with EventTarget.addEventListener() (from MDN web docs).

The event listener to be removed is identified combining:

  • event type
  • event listener function itself
  • various optional options

For example, assuming we registered an event listener with the following statement:

element.addEventListener("keyup", handleKeyUp);

in order to stopping listening to the specific event, we simply execute:

element.removeEventListener("keyup", handleKeyUp);

In case some options were specified at the moment of registering the event, they must also match when removing the listener. Therefore, if we previously registered the following:

element.addEventListener("mousedown", handleMouseDown, true);

executing the following two statements, only one will have the desired result:

element.removeEventListener("mousedown", handleMouseDown, false); 
element.removeEventListener("mousedown", handleMouseDown, true);

The first statement will not correctly remove the event listener. This is because the value of useCapture does not match with the one specified at the moment of the event listener registration.


Let’s come to anonymous functions now, which also inspired me to write this article. How do we remove an event listener from an element, if the registered callback to be executed has been defined as an anonymous function?

Assuming we add the following event listener:

element.addEventListener("click", function() {
// do something
}, true);

we might think that in order to remove the listener we could execute:

element.removeEventListener("click", function() {
// do the same of above
}, true);

but this won’t have any effect. This is because the two anonymous functions are completely different functions. The removeEventListener's argument is not a reference to the function object that was previously attached.

One solution would be storing the reference to the function into a variable:

var _listener = function() {
// do something
}
element.addEventListener("click", _listener, true);
element.removeEventListener("click", _listener, true);

In this case, the event listener will be successfully removed because the removeEventListener's argument matches the reference to the function object of the addEventListener.

In case, for any reason, you can’t or don’t want store the object function, there is another solution. Which simply is, to don’t use an anonymous function and giving a name to the function callback.

element.addEventListener("click", function _listener() {
// do something

element.removeEventListener("click", _listener, true);
}, true);