Plain JavaScript prevent eventListener being executed twice

2.4k views Asked by At

I've been breaking my head on the following. In the MDN Documentation on EventTarget.addEventListener() the following is stated:

Multiple identical event listeners

If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice, and since the duplicates are discarded, they do not need to be removed manually with the removeEventListener method.

Which is a great thing. So I cannot add a duplicate EventListener on an element, but how do I find out if there is already an EventListener attached to another element somewhere in the DOM?

Say, I have an event called expandNavigationGroup, which is fired whenever my navigationpanel is clicked to open a navigationgroup. I can attach a listener for this event anywhere in my DOM. For instance:

var el = document.getElementById("somediv");
el.addEventListener("expandNavigationGroup", doSomething, false);

The doSomething method does something relevant, like cleaning something up. It needs to be done once, but only once, when a navigationgroup is opened, but if my code does the following:

var el = document.getElementById("someotherdiv");
el.addEventListener("expandNavigationGroup", doSomething, false);

The EventListener is added twice, and my cleanup code is executed twice.

How can I prevent this from happening?

3

There are 3 answers

1
Harshit Jain On

According to MDN Documentation If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. You are registering event on different targets somediv and someotherdiv and hence the cleanup code is executed twice.

4
halbgut On

@Chris is right. The only thing you could do is use some kind of "_.once" function.

Here's an implementation:

var once = (function (func) {
  var wasExecuted = false
  return function onceExecuter () {
    if(wasExecuted) {
      wasExecuted = true
      return func.apply(null, arguments)
    }
  }
})()

Now you can do this:

var doSomethingOnce = once(doSomething)
doSomething()
doSomething()

And doSomething is executed once

0
Chris On

Since you are not registering the EventListeners on the same EventTarget you would have to remove the EventListeners manually.

var el = document.getElementById("somediv");
el.addEventListener("expandNavigationGroup", doSomething, false);
el.removeEventListener('expandNavigationGroup', doSomething, false);

var el = document.getElementById("someotherdiv");
el.addEventListener("expandNavigationGroup", doSomething, false);
el.removeEventListener('expandNavigationGroup', doSomething, false);