0

I'm trying to store Listener functions so that I can remove them later. I'm using a wrapper to add listeners. The issue is that the listeners are not removed. Why is that?

Below is some code:

    classMyClass{
      // add the wrapper to event listener
       init(){ 
        window.app.addEventListener = function(type, fn, opt){
           obj.listeners.push({type: type, fn: fn, opt: opt});
           console.log('addEvent ', l);
           var l = obj.listeners[obj.listeners.length-1];
           console.log(l);
           window.addEventListener(l.type, l.fn, l.opt);
           //window.removeEventListener(l.type, l.fn, l.opt);
        };
      }
       removeListeners(){
        let obj = this;
        this.listeners.forEach(function() {
           var l = obj.listeners[obj.listeners.length-1];
           console.log('remove ', l);
          // remove the listener
           window.removeEventListener(l.type, l.fn, l.opt);
           obj.listeners.pop();
       });
   }
mike
  • 533
  • 1
  • 7
  • 24
  • you are making this WAY too hard on yourself. Write simple functions (or class methods if you prefer) that are called by name as handlers. When it is time to remove them, simply refer to the same function name. Easy. – Randy Casburn Dec 12 '18 at 01:30
  • 1
    what is `obj` in `init()`? – yqlim Dec 12 '18 at 01:32
  • How is this class used? – Felix Kling Dec 12 '18 at 01:35
  • @RandyCasburn classMyClass does not know about the functions/components adding listeners. I'm trying to build a mini SPA router that removes all the listeners once a new page is loaded. – mike Dec 12 '18 at 01:39
  • @FelixKling it's used as a single page application router. I need to remove all the listeners when a new page is loaded. – mike Dec 12 '18 at 01:41
  • Then I recommend you consider Proxy Objects to intercept `addEventListener()` calls if using modern browsers - this is the modern approach. Otherwise, you'll have to clone any node with listeners to get rid of them. Here are a couple of related questions: https://stackoverflow.com/questions/9251837/how-to-remove-all-listeners-in-an-element and https://stackoverflow.com/questions/19469881/remove-all-event-listeners-of-specific-type/46986927 – Randy Casburn Dec 12 '18 at 01:46

1 Answers1

0

The event handler has to be registered with a named function.

If you really have to, you can try something like this:

var eventListener = (function()
    function eventCallback() { ... /* whatever that needs to be done for an event */ ... }
    return {
        activate: function() {
            addEventListener(/* add the type of event */, eventCallback);
            console.log("event listener added."); //if you want this here
        },

        deactivate: function() {
            removeEventListener(eventCallback); //removes the event
            console.log("event listener removed."); //if you want this here
        },
    }
)();

Then, you'd be able to enable the listener with eventListener.activate() and disable it with eventListener.deactivate(). Keep in mind, this solution works for one event only.

If you want to store multiple event functions to be stored, then you can do an array of eventListener.

The main thing here is to name the functions, so you can refer to them later to remove the event listener.

Tilepaper
  • 78
  • 5
  • The event handler _doesn't_ have to be a named function, it can be anonymous — for example, this works perfectly: `document.querySelector('body').addEventListener('click', function(e) { alert('click event: ' + e); });` The problem comes in when you want to remove them, you need a way to reference them. I think you could be a little clearer about that. – Stephen P Dec 12 '18 at 17:38