删除事件监听器vanilla JS

时间:2015-08-11 13:20:50

标签: javascript javascript-events

我在这支钢笔中描述的特殊情景尽可能短:http://codepen.io/tuelsch/pen/rVRRNm?editors=101

这篇文章(Adding and Removing Event Listeners with parameters)指出了我正确的方向,但设置不同。

我喜欢有一个自定义JS对象(Film),它可以在link属性(DOM元素)上添加和删除事件处理程序。

我遇到了第18行的removeEvent函数。在这种情况下,removeEventListener函数的第二个参数是正确的吗?

不是添加和删除事件监听器,而是继续添加事件监听器,这可以在控制台中观察到,其中记录了第8行的结果。

解决方案应该是普通的jilla,兼容ES5并且打算在浏览器中运行(IE9 +)。

2 个答案:

答案 0 :(得分:2)

  1. 您可以先在对象中保留该绑定事件的记录,如:
  2. // Add the event handler
    Film.prototype.bindEvent = function () {
      // This ensure that the binded event can be removed by removeEvent
      // even if you call bindEvent many times.
      if (!this._bindedEvent) {
        this._bindedEvent = this.eventHandler.bind(this);
        this.link.addEventListener('click', this._bindedEvent);
      }
    }
    

    然后删除:

    // Remove the event handler
    Film.prototype.removeEvent = function () {
      if (this._bindedEvent) {
        this.link.removeEventListener('click', this._bindedEvent); 
        this._bindedEvent = null;
      }
    }
    

    2。另一种方法是在构造函数中重写eventhandler

    // The test class definition
    var Film = function () {
      this.link = document.getElementById('film');
      // This first find if self has attr eventHandler, and keep lookup to its prototype.
      // Then createa binded version of eventhandler and set to this's attr.
      // So when you try to access `this.eventHandler`, it'll be the binded version instead of Prototype's
      this.eventHandler = this.eventHandler.bind(this);
    }
    

    然后你可以使用

    // Add the event handler
    Film.prototype.bindEvent = function () {
        this.link.addEventListener('click', this.eventHandler);
    }
    
    // Remove the event handler
    Film.prototype.removeEvent = function () {
        this.link.removeEventListener('click', this.eventHandler); 
    }
    

    添加和删除它。

答案 1 :(得分:1)

当你在这里使用.bind(this)this.link.addEventListener('click', this.eventHandler.bind(this));时,你实际上得到了一个新功能。当您尝试删除它时,您使用原始处理程序,并且删除无法找到绑定的处理程序。

来自MDN

  

bind()方法创建一个新函数,当被调用时,它具有它   此关键字设置为提供的值,具有给定的序列   调用新函数时提供的任何参数。

要修复它,在定义处理程序时使用bind(codepen - 处理程序在3秒后被删除):

// The event handler to add and remove
Film.prototype.eventHandler = function () {
  console.log('handled');
}.bind(Film);

// Add the event handler
Film.prototype.bindEvent = function () {
  this.link.addEventListener('click', this.eventHandler);
}

// Remove the event handler
Film.prototype.removeEvent = function () {
  this.link.removeEventListener('click', this.eventHandler);
}