在JavaScript中,什么是去除使用绑定为一个事件侦听器附加功能的最佳方法()?
例
(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", ___________);
};
})();
我能想到的唯一的办法就是跟踪与绑定添加每一位聆听者的。
上面的例子中使用这种方法:
(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);
};
})();
是否有更好的方式来做到这一点?
Answer 1:
虽然什么@machineghost说的是真的,那事件,并移除同样的方法,公式的缺失的部分是这样的:
之后创建一个新的函数参考.bind()
被调用!
见不绑定()改变功能引用? | 如何永久设置?
因此,添加或删除,分配参照变量:
var x = this.myListener.bind(this);
Toolbox.addListener(window, 'scroll', x);
Toolbox.removeListener(window, 'scroll', x);
这按预期工作对我来说。
Answer 2:
对于那些在注册/删除组件做出反应/从通量店,下面添加到您的组件的构造线的听众谁拥有这个问题:
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() { // ... } }
Answer 3:
不要紧,你是否使用绑定功能或没有; 你删除它以同样的方式与任何其他事件处理程序。 如果你的问题是绑定的版本是其独特的功能,你可以跟踪绑定版本,或者使用removeEventListener
不采取特定处理器(签名虽然当然,将删除相同的其他事件处理程序类型)。
(作为一个方面说明, addEventListener
不会在所有的浏览器。你真的应该使用一个库如jQuery做你的事件挂接起坐在一个跨浏览器的方式为您另外,jQuery有命名空间的事件,的概念,让你绑定到“click.foo”;当你想删除你可以告诉jQuery的“删除所有富事件”,而不知道具体的处理程序或删除其他处理的事件)
Answer 4:
jQuery的解决方案:
let object = new ClassName();
let $elem = $('selector');
$elem.on('click', $.proxy(object.method, object));
$elem.off('click', $.proxy(object.method, object));
Answer 5:
这里是解决方案:
var o = {
list: [1, 2, 3, 4],
add: function () {
var b = document.getElementsByTagName('body')[0];
b.addEventListener('click', this._onClick());
},
remove: function () {
var b = document.getElementsByTagName('body')[0];
b.removeEventListener('click', this._onClick());
},
_onClick: function () {
this.clickFn = this.clickFn || this._showLog.bind(this);
return this.clickFn;
},
_showLog: function (e) {
console.log('click', this.list, e);
}
};
// Example to test the solution
o.add();
setTimeout(function () {
console.log('setTimeout');
o.remove();
}, 5000);
Answer 6:
我们有这个问题,我们不能更改库。 办公面料UI,这意味着我们无法改变添加事件处理程序的方式。 我们解决它的方法是覆盖addEventListener
对EventTarget
的原型。
这将添加一个新功能上的对象element.removeAllEventListers("click")
(原帖: 取下布对话框覆盖Click处理程序 )
<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>
Answer 7:
如果你想使用的“onClick”,如上面所说,你可以试试这个:
(function(){
var singleton = {};
singleton = new function() {
this.myButton = document.getElementById("myButtonID");
this.myButton.onclick = function() {
singleton.clickListener();
};
}
singleton.clickListener = function() {
console.log(this); // I also know who I am
};
// public function
singleton.disableButton = function() {
this.myButton.onclick = "";
};
})();
我希望它能帮助。
Answer 8:
它已经一段时间,但MDN对这个超级解释。 这让我比这里的东西更多。
MDN :: EventTarget.addEventListener -的“本”的处理程序中的价值
它给到的handleEvent函数的理想替代品。
这是有和没有绑定的示例:
var Something = function(element) {
this.name = 'Something Good';
this.onclick1 = function(event) {
console.log(this.name); // undefined, as this is the element
};
this.onclick2 = function(event) {
console.log(this.name); // 'Something Good', as this is the binded Something object
};
element.addEventListener('click', this.onclick1, false);
element.addEventListener('click', this.onclick2.bind(this), false); // Trick
}
在上面的例子中的一个问题是,你不能用绑定删除侦听。 另一种解决方案是使用所谓的handleEvent一个特殊的函数来捕捉任何事件:
文章来源: Removing event listener which was added with bind