如何在 class 中的(范围内的)addEventListener 上应用 removeEventListener?
How do I apply removeEventListener on an (scoped) addEventListener in a class?
在全局范围内,您可以删除 eventListener。下一个代码可以工作,并且可以显示所需的行为;第一个按钮触发改变,第二个按钮不触发。
window.addEventListener('load', () => {
const button1 = document.getElementById('button-1');
const button2 = document.getElementById('button-2');
button1.addEventListener('click', helloAlert);
button2.addEventListener('click', helloAlert);
button2.removeEventListener('click', helloAlert);
});
function helloAlert(){
window.alert('hello');
};
<button id='button-1'>addEventListener</button>
<button id='button-2'>addEventListener & removeEventListener</button>
在 OOP 情况下,我最终会遇到这样的情况。
window.addEventListener('load', () => {
let button1 = document.getElementById('button-1');
let messenger1 = new Messenger( button1, 'hello 1' );
messenger1.addHelloAlert();
let button2 = document.getElementById('button-2');
let messenger2 = new Messenger( button2, 'hello-2' );
messenger2.addHelloAlert();
messenger2.removeHelloAlert();
});
class Messenger{
constructor( button, message ){
this.button = button;
this.text = message;
}
addHelloAlert(){
this.button.addEventListener('click', this.giveMessage.bind(this));
}
removeHelloAlert(){
// this is where I get stuck because
// I cannot reference to the relevant function
// to remove the eventListener
this.button.removeEventListener('click', this.giveMessage );
}
giveMessage(){
window.alert( this.text );
};
}
<button id='button-1'>addEventListener</button>
<button id='button-2'>addEventListener & removeEventListener</button>
如您所见,OOP 代码未删除 eventListener,因为未选择该函数。
有人知道如何在 常规 JavaScript 和 OOP 中解决这个问题吗?
一个选项是 bind
构造函数 中的 this.giveMessage
处理程序,这样以后就可以随意添加和删除它而无需进一步绑定,当涉及处理程序时,在像 React 这样的框架中经常看到:
class Messenger {
constructor(button, message) {
this.button = button;
this.text = message;
this.giveMessage = this.giveMessage.bind(this);
}
addHelloAlert() {
this.button.addEventListener('click', this.giveMessage);
}
removeHelloAlert() {
this.button.removeEventListener('click', this.giveMessage);
}
giveMessage() {
console.log(this.text);
};
}
let button1 = document.getElementById('button-1');
let messenger1 = new Messenger(button1, 'hello 1');
messenger1.addHelloAlert();
let button2 = document.getElementById('button-2');
let messenger2 = new Messenger(button2, 'hello-2');
messenger2.addHelloAlert();
messenger2.removeHelloAlert();
<button id='button-1'>addEventListener</button>
<button id='button-2'>addEventListener & removeEventListener</button>
如果您出于某种原因(如封装/隐私)不想将绑定的侦听器附加到 实例 ,另一种选择是分配给外部作用域 Map
.
在全局范围内,您可以删除 eventListener。下一个代码可以工作,并且可以显示所需的行为;第一个按钮触发改变,第二个按钮不触发。
window.addEventListener('load', () => {
const button1 = document.getElementById('button-1');
const button2 = document.getElementById('button-2');
button1.addEventListener('click', helloAlert);
button2.addEventListener('click', helloAlert);
button2.removeEventListener('click', helloAlert);
});
function helloAlert(){
window.alert('hello');
};
<button id='button-1'>addEventListener</button>
<button id='button-2'>addEventListener & removeEventListener</button>
在 OOP 情况下,我最终会遇到这样的情况。
window.addEventListener('load', () => {
let button1 = document.getElementById('button-1');
let messenger1 = new Messenger( button1, 'hello 1' );
messenger1.addHelloAlert();
let button2 = document.getElementById('button-2');
let messenger2 = new Messenger( button2, 'hello-2' );
messenger2.addHelloAlert();
messenger2.removeHelloAlert();
});
class Messenger{
constructor( button, message ){
this.button = button;
this.text = message;
}
addHelloAlert(){
this.button.addEventListener('click', this.giveMessage.bind(this));
}
removeHelloAlert(){
// this is where I get stuck because
// I cannot reference to the relevant function
// to remove the eventListener
this.button.removeEventListener('click', this.giveMessage );
}
giveMessage(){
window.alert( this.text );
};
}
<button id='button-1'>addEventListener</button>
<button id='button-2'>addEventListener & removeEventListener</button>
如您所见,OOP 代码未删除 eventListener,因为未选择该函数。
有人知道如何在 常规 JavaScript 和 OOP 中解决这个问题吗?
一个选项是 bind
构造函数 中的 this.giveMessage
处理程序,这样以后就可以随意添加和删除它而无需进一步绑定,当涉及处理程序时,在像 React 这样的框架中经常看到:
class Messenger {
constructor(button, message) {
this.button = button;
this.text = message;
this.giveMessage = this.giveMessage.bind(this);
}
addHelloAlert() {
this.button.addEventListener('click', this.giveMessage);
}
removeHelloAlert() {
this.button.removeEventListener('click', this.giveMessage);
}
giveMessage() {
console.log(this.text);
};
}
let button1 = document.getElementById('button-1');
let messenger1 = new Messenger(button1, 'hello 1');
messenger1.addHelloAlert();
let button2 = document.getElementById('button-2');
let messenger2 = new Messenger(button2, 'hello-2');
messenger2.addHelloAlert();
messenger2.removeHelloAlert();
<button id='button-1'>addEventListener</button>
<button id='button-2'>addEventListener & removeEventListener</button>
如果您出于某种原因(如封装/隐私)不想将绑定的侦听器附加到 实例 ,另一种选择是分配给外部作用域 Map
.