我正在使用ES6类定义来创建小组件,在其他事物之间,将侦听器附加到元素。由于我将类方法绑定为侦听器回调,因此我在事件执行期间使用.bind()
来保留上下文。
为了澄清,我写了一篇非常有人工作的课程:
class Test {
constructor(el) {
this.x = 10;
this.elem = el;
this.elem.addEventListener('click', this.listenerFn.bind(this));
}
listenerFn(ev) {
console.log(this.x);
}
}
如果我想稍后破坏此组件并从元素中分离侦听器而不破坏元素本身,则会引发问题。由于使用.bind()
创建了一个新功能,因此仅仅引用this.listenerFn
是不够的。
我想到的是创建一个侦听器地图并在连接/分离时使用它们。
像这样:
class Test {
constructor(el) {
this.x = 10;
this.elem = el;
this.listenerPool = {
'click': this.listenerFn.bind(this),
}
this.elem.addEventListener('click', this.listenerPool.click);
this.elem.test = {
destroy: this.destroy.bind(this),
}
}
listenerFn(ev) {
console.log(this.x);
}
destroy() {
this.elem.removeEventListener('click', this.listenerPool.click);
delete this.elem.test;
}
}
//...
new Test(document.querySelector('#some_id'));
document.querySelector('#some_id').test.destroy();
虽然它有效,但它没有利用原型方法,而是为每个类的实例创建一个新副本,所以我想知道:这是正确的吗?
如果人们可以针对同一问题分享不同的解决方案,我也将不胜感激。
答案 0 :(得分:1)
您不需要整个listenerPool
来执行此操作,但通常所做的是将成员方法显式绑定到constructor
中的实例:
class Test {
constructor(el) {
this.x = 10;
this.elem = el;
this.listenerFn = this.listenerFn.bind(this);
this.elem.addEventListener('click', this.listenerFn);
// ...
}
listenerFn(ev) {
console.log(this.x);
}
destroy() {
this.elem.removeEventListener('click', this.listenerFn);
}
}
您还希望避免将随机用户对象附加到elem.test = { destroy: ... }
等本机对象,因为这非常类似于创建全局变量,因此请尝试从调用中找到另一种方法来调用类的destroy()
方法脚本没有直接附加到元素。
我会就如何提供更具体的建议,但你没有提供调用代码。