Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing event listener which was added with bind

People also ask

How do I remove a specific event listener?

Event listeners can also be removed by passing an AbortSignal to an addEventListener() and then later calling abort() on the controller owning the signal.

How do I remove event listener inside event listener?

To remove the "click" event listener attached from the <script> tag above, you need to use the removeEventListener() method, passing the type of the event and the callback function to remove from the element: button. removeEventListener("click", fnClick);

Should I remove event listeners before removing elements?

Removing the event listener first always results in lower memory usage (no leaks). Results: IE6 - memory leak.

When should an event listener be removed?

TLDR; Always remove event listeners when you don't plan on using them any longer.


Although what @machineghost said was true, that events are added and removed the same way, the missing part of the equation was this:

A new function reference is created after .bind() is called.

See Does bind() change the function reference? | How to set permanently?

So, to add or remove it, assign the reference to a variable:

var x = this.myListener.bind(this);
Toolbox.addListener(window, 'scroll', x);
Toolbox.removeListener(window, 'scroll', x);

This works as expected for me.


For those who have this problem while registering/removing listener of React component to/from Flux store, add the lines below to the constructor of your component:

class App extends React.Component {
  constructor(props){
    super(props);
    // it's a trick! needed in order to overcome the remove event listener
    this.onChange = this.onChange.bind(this);  
  }
  // then as regular...
  componentDidMount (){
    AppStore.addChangeListener(this.onChange);
  }
  
  componentWillUnmount (){
    AppStore.removeChangeListener(this.onChange);
  }

  onChange () {
    let state = AppStore.getState();
    this.setState(state);
  }
  
  render() {
    // ...
  }
  
}

It doesn't matter whether you use a bound function or not; you remove it the same way as any other event handler. If your issue is that the bound version is its own unique function, you can either keep track of the bound versions, or use the removeEventListener signature that doesn't take a specific handler (although of course that will remove other event handlers of the same type).

(As a side note, addEventListener doesn't work in all browsers; you really should use a library like jQuery to do your event hook-ups in a cross-browser way for you. Also, jQuery has the concept of namespaced events, which allow you to bind to "click.foo"; when you want to remove the event you can tell jQuery "remove all foo events" without having to know the specific handler or removing other handlers.)


jQuery solution:

let object = new ClassName();
let $elem = $('selector');

$elem.on('click', $.proxy(object.method, object));

$elem.off('click', $.proxy(object.method, object));

We had this problem with a library we could not change. Office Fabric UI, which meant we could not change the way event handlers were added. The way we solved it was to overwrite the addEventListener on the EventTarget prototype.

This will add a new function on objects element.removeAllEventListers("click")

(original post: Remove Click handler from fabric dialog overlay)

        <script>
            (function () {
                "use strict";

                var f = EventTarget.prototype.addEventListener;

                EventTarget.prototype.addEventListener = function (type, fn, capture) {
                    this.f = f;
                    this._eventHandlers = this._eventHandlers || {};
                    this._eventHandlers[type] = this._eventHandlers[type] || [];
                    this._eventHandlers[type].push([fn, capture]);
                    this.f(type, fn, capture);
                }

                EventTarget.prototype.removeAllEventListeners = function (type) {
                    this._eventHandlers = this._eventHandlers || {};
                    if (type in this._eventHandlers) {
                        var eventHandlers = this._eventHandlers[type];
                        for (var i = eventHandlers.length; i--;) {
                            var handler = eventHandlers[i];
                            this.removeEventListener(type, handler[0], handler[1]);
                        }
                    }
                }

                EventTarget.prototype.getAllEventListeners = function (type) {
                    this._eventHandlers = this._eventHandlers || {};
                    this._eventHandlers[type] = this._eventHandlers[type] || [];
                    return this._eventHandlers[type];
                }

            })();
        </script>