无法移除 eventListener,试了 6 小时
Can't remove eventListener, tried for 6 hours
我已经尝试了几个小时删除事件侦听器,但没有成功。
由于我进行了测试,我了解到问题可能出在听众参考上。
这是代码。为了清晰起见,我剥离并简化了所有内容。
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
complete(e){
e.currentTarget.removeEventListener(COMPLETE, this.complete);
console.log('I run only once');
}
}
let child = new Template();
child.exe = function(){
dispatcher.addEventListener(COMPLETE, this.complete.bind(this));
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
当然在控制台中你可以读三遍“I 运行 only once”。
我所做的测试涉及额外的变量 'functionReference',我在其中存储侦听器引用。然后就可以了。
let functionReference
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
complete(e){
e.currentTarget.removeEventListener(COMPLETE, functionReference);
console.log('i run only once');
}
}
let child = new Template();
child.exe = function(){
functionReference = this.complete.bind(this);
dispatcher.addEventListener(COMPLETE, functionReference);
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
现在在控制台中只有一次“我 运行 只有一次”。
这是怎么回事?为什么我不能删除那个监听器?
***** 下面的更新/解决方案
***非常感谢 Teemu 和 amrender singh
谢谢 amrender singh 的解释!
并感谢你 Teemu 的好主意和解决方案!
非常感谢您的快速帮助!好多年没这么卡了
下面的 Teemu 解决方案:
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
constructor(){
this.complete = (e)=>{
e.currentTarget.removeEventListener(COMPLETE, this.complete);
console.log('i run only once');
}
}
}
let child = new Template();
child.exe = function(){
dispatcher.addEventListener(COMPLETE, this.complete);
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
或者,可以存储对侦听器的引用并将其作为变量传递。
来自 MDN:
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
在第一个例子中:
dispatcher.addEventListener(COMPLETE, this.complete.bind(this));
绑定创建一个新函数并将其附加为处理程序。这就是为什么您无法删除事件侦听器,因为您之前使用 bind 附加的事件侦听器与您的完整方法不同。
在你的第二个例子中:
functionReference = this.complete.bind(this);
dispatcher.addEventListener(COMPLETE, functionReference);
您正在将 bind 返回的新函数注册为侦听器,然后将其删除,因为在两个 add/remove 中侦听器是相同的,这就是它被删除的原因。
我已经尝试了几个小时删除事件侦听器,但没有成功。
由于我进行了测试,我了解到问题可能出在听众参考上。
这是代码。为了清晰起见,我剥离并简化了所有内容。
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
complete(e){
e.currentTarget.removeEventListener(COMPLETE, this.complete);
console.log('I run only once');
}
}
let child = new Template();
child.exe = function(){
dispatcher.addEventListener(COMPLETE, this.complete.bind(this));
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
当然在控制台中你可以读三遍“I 运行 only once”。
我所做的测试涉及额外的变量 'functionReference',我在其中存储侦听器引用。然后就可以了。
let functionReference
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
complete(e){
e.currentTarget.removeEventListener(COMPLETE, functionReference);
console.log('i run only once');
}
}
let child = new Template();
child.exe = function(){
functionReference = this.complete.bind(this);
dispatcher.addEventListener(COMPLETE, functionReference);
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
现在在控制台中只有一次“我 运行 只有一次”。
这是怎么回事?为什么我不能删除那个监听器?
***** 下面的更新/解决方案 ***非常感谢 Teemu 和 amrender singh
谢谢 amrender singh 的解释! 并感谢你 Teemu 的好主意和解决方案! 非常感谢您的快速帮助!好多年没这么卡了
下面的 Teemu 解决方案:
const COMPLETE = 'complete';
let dispatcher = new EventTarget;
class Template {
constructor(){
this.complete = (e)=>{
e.currentTarget.removeEventListener(COMPLETE, this.complete);
console.log('i run only once');
}
}
}
let child = new Template();
child.exe = function(){
dispatcher.addEventListener(COMPLETE, this.complete);
}
child.exe();
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
dispatcher.dispatchEvent(new Event(COMPLETE));
或者,可以存储对侦听器的引用并将其作为变量传递。
来自 MDN:
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
在第一个例子中:
dispatcher.addEventListener(COMPLETE, this.complete.bind(this));
绑定创建一个新函数并将其附加为处理程序。这就是为什么您无法删除事件侦听器,因为您之前使用 bind 附加的事件侦听器与您的完整方法不同。
在你的第二个例子中:
functionReference = this.complete.bind(this);
dispatcher.addEventListener(COMPLETE, functionReference);
您正在将 bind 返回的新函数注册为侦听器,然后将其删除,因为在两个 add/remove 中侦听器是相同的,这就是它被删除的原因。