Eliminando el detector de eventos que se agregó con bind

Resuelto takfuruya asked hace 12 años • 10 respuestas

En JavaScript, ¿cuál es la mejor manera de eliminar una función agregada como detector de eventos usando bind()?

Ejemplo

(function(){

    // constructor
    MyClass = function() {
        this.myButton = document.getElementById("myButtonID");
        this.myButton.addEventListener("click", this.clickListener.bind(this));
    };

    MyClass.prototype.clickListener = function(event) {
        console.log(this); // must be MyClass
    };

    // public method
    MyClass.prototype.disableButton = function() {
        this.myButton.removeEventListener("click", ___________);
    };

})();

La única forma que se me ocurre es realizar un seguimiento de cada oyente agregado con bind.

Ejemplo anterior con este método:

(function(){

    // constructor
    MyClass = function() {
        this.myButton = document.getElementById("myButtonID");
        this.clickListenerBind = this.clickListener.bind(this);
        this.myButton.addEventListener("click", this.clickListenerBind);
    };

    MyClass.prototype.clickListener = function(event) {
        console.log(this); // must be MyClass
    };

    // public method
    MyClass.prototype.disableButton = function() {
        this.myButton.removeEventListener("click", this.clickListenerBind);
    };

})();

¿Hay alguna manera mejor de hacer esto?

takfuruya avatar Jul 19 '12 23:07 takfuruya
Aceptado

Aunque lo que dijo @machineghost era cierto, que los eventos se agregan y eliminan de la misma manera, la parte que faltaba en la ecuación era esta:

Se crea una nueva referencia de función después de .bind()llamarla.

Consulte ¿Bind() cambia la referencia de la función? | ¿Cómo configurarlo permanentemente?

Entonces, para agregarlo o eliminarlo, asigna la referencia a una variable:

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

Esto funciona como se esperaba para mí.

Ben avatar Apr 04 '2014 18:04 Ben

Para aquellos que tienen este problema al registrar/eliminar el oyente del componente React hacia/desde la tienda Flux, agregue las siguientes líneas al constructor de su componente:

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() {
    // ...
  }
  
}
Expandir fragmento

Raichman Sergey avatar Oct 28 '2015 08:10 Raichman Sergey