我有一个标签,该标签在JS应用程序中的某个时候会获得click eventListener。并意外地进一步获得了第二个单击事件侦听器。我希望先删除第一个,然后再添加。
我如何使用chrome dev工具确定何时添加,删除事件侦听器以及导致它的代码(包括调用堆栈)?
我尝试过控制台日志记录,但是仍然看不到原因。
在这样的功能中完成监听器的添加和删除
class SomeClass {
/**
* Enables listeners so that clicking on the navigatableElement can work.
*/
enableListeners() {
this.disableListeners();
this._navigatableElement.addEventListener('click', this._clickEventHandler.bind(this));
}
/**
* Disables listeners so that clicking on the navigatableElement will never trigger the confirmation modal anymore via this controller
*/
disableListeners() {
this._navigatableElement.removeEventListener('click', this._clickEventHandler.bind(this));
}
}
答案 0 :(得分:1)
您的删除代码无效,因为每次对.bind()
的调用都会生成一个新的函数对象。您要删除浏览器没有看到的注册监听器,并且会忽略该呼叫。
答案 1 :(得分:1)
可用于调试(但不能在生产代码中使用)的一种可能的方法是写入Element.prototype.addEventListener
,使您可以在每次调用console.trace
时进行登录和记录:
const { addEventListener, removeEventListener } = EventTarget.prototype;
Element.prototype.addEventListener = function(...args) {
console.log('Adding event listener!', this, args);
console.trace();
// debugger
return addEventListener.apply(this, args);
};
Element.prototype.removeEventListener = function(...args) {
console.log('Removing event listener!', this, args);
console.trace();
// debugger
return removeEventListener.apply(this, args);
};
console.log('real script start');
const fn = () => console.log('fn');
foo.addEventListener('click', fn);
console.log('listener added.');
foo.removeEventListener('click', fn);
<div id="foo">
</div>
您的特定代码无法正常工作,因为每次.bind
都在创建一个新函数。您可以在构造函数中使用常见的React绑定模式,这样对this._clickEventHandler
的每次引用都将指向同一函数。 ({removeEventListener
的调用必须与调用函数addEventListener
的功能完全相同。)
class SomeClass {
constructor() {
this._clickEventHandler = this._clickEventHandler.bind(this);
}
/**
* Enables listeners so that clicking on the navigatableElement can work.
*/
enableListeners() {
this.disableListeners();
this._navigatableElement.addEventListener('click', this._clickEventHandler);
}
/**
* Disables listeners so that clicking on the navigatableElement will never trigger the confirmation modal anymore via this controller
*/
disableListeners() {
this._navigatableElement.removeEventListener('click', this._clickEventHandler);
}
}