我在这支钢笔中描述的特殊情景尽可能短: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 +)。
答案 0 :(得分: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);
}