Vanilla JS 移除柯里化函数中的事件监听器
Vanilla JS remove eventlistener in currying function
我有一个非常“简单”的 vanillaJS 问题。如何在 currying 函数内的循环中删除事件侦听器?这只是我当前解决方案的一个示例,我实际上需要多个参数传给侦听器。如果我是对的,我怀疑由于匿名回调而没有删除事件监听器?我怎样才能解决这个问题?这里的例子 https://codepen.io/shnigi/pen/wvPwqVR
const setEventListener = (buttons) => (event) => {
const buttonValue = event.target.value;
console.log('Eventlistener exists', buttonValue)
buttons.forEach(button => button.removeEventListener('click', setEventListener));
};
const buttons = document.querySelectorAll('button');
buttons.forEach(button => button.addEventListener('click', setEventListener(buttons)));
// Works as expected, listener is named
const testbutton = document.getElementById('kek');
const testListener = () => {
console.log('I show up only once');
testbutton.removeEventListener('click', testListener);
};
testbutton.addEventListener('click', testListener);
<button value="1">press me</button>
<button value="2">press me</button>
<button id="kek">eventlistener removed on click</button>
I suspect that the event listener is not removed due to anonymous callback if I am right?
是的,这是一个问题。
所以你必须将匿名函数分配给变量并使用它来删除事件监听器。
这是给你的示例代码。
const setEventListener = (buttons: NodeList) => {
const returnedFunc = (event: Event) => {
const buttonValue = (event.target as HTMLButtonElement).value;
console.log('Eventlistener exists', buttonValue)
buttons.forEach(button => button.removeEventListener('click', returnedFunc));
};
return returnedFunc;
};
const buttons: Nodelist = document.querySelectorAll('button');
buttons.forEach(button => button.addEventListener('click', setEventListener(buttons)));
// Works as expected, listener is named
const testbutton = document.getElementById('kek');
const testListener = () => {
console.log('I show up only once');
testbutton.removeEventListener('click', testListener);
};
testbutton.addEventListener('click', testListener);
如果您不关心 Internet Explorer 支持,您可以使用 AbortController 以更优雅的方式删除匿名事件侦听器。将 signal
选项传递给 addEventListener()
并在要删除事件侦听器时调用 AbortController 的 abort()
方法:
var listenersRemover = new AbortController();
button.addEventListener('click', callback, {signal: listenersRemover.signal}));
listenersRemover.abort();
Note
:您应该“重新武装”中止控制器以对新的 addEventListener()
调用使用相同的信号。只需使用 new AbortController()
.
再次初始化它
var listenersRemover = new AbortController();
const setEventListener = (buttons) => (event) => {
const buttonValue = event.target.value;
console.log('Eventlistener exists', buttonValue)
// buttons.forEach(button => button.removeEventListener('click', setEventListener));
};
const buttons = document.querySelectorAll('button');
buttons.forEach(button => button.addEventListener('click', setEventListener(buttons), {signal: listenersRemover.signal}));
// Works as expected, listener is named
const testbutton = document.getElementById('kek');
const testListener = () => {
console.log('I show up only once');
//testbutton.removeEventListener('click', testListener);
listenersRemover.abort();
};
testbutton.addEventListener('click', testListener, {signal: listenersRemover.signal});
<button value="1">press me</button>
<button value="2">press me</button>
<button id="kek">eventlistener removed on click</button>
我有一个非常“简单”的 vanillaJS 问题。如何在 currying 函数内的循环中删除事件侦听器?这只是我当前解决方案的一个示例,我实际上需要多个参数传给侦听器。如果我是对的,我怀疑由于匿名回调而没有删除事件监听器?我怎样才能解决这个问题?这里的例子 https://codepen.io/shnigi/pen/wvPwqVR
const setEventListener = (buttons) => (event) => {
const buttonValue = event.target.value;
console.log('Eventlistener exists', buttonValue)
buttons.forEach(button => button.removeEventListener('click', setEventListener));
};
const buttons = document.querySelectorAll('button');
buttons.forEach(button => button.addEventListener('click', setEventListener(buttons)));
// Works as expected, listener is named
const testbutton = document.getElementById('kek');
const testListener = () => {
console.log('I show up only once');
testbutton.removeEventListener('click', testListener);
};
testbutton.addEventListener('click', testListener);
<button value="1">press me</button>
<button value="2">press me</button>
<button id="kek">eventlistener removed on click</button>
I suspect that the event listener is not removed due to anonymous callback if I am right?
是的,这是一个问题。 所以你必须将匿名函数分配给变量并使用它来删除事件监听器。
这是给你的示例代码。
const setEventListener = (buttons: NodeList) => {
const returnedFunc = (event: Event) => {
const buttonValue = (event.target as HTMLButtonElement).value;
console.log('Eventlistener exists', buttonValue)
buttons.forEach(button => button.removeEventListener('click', returnedFunc));
};
return returnedFunc;
};
const buttons: Nodelist = document.querySelectorAll('button');
buttons.forEach(button => button.addEventListener('click', setEventListener(buttons)));
// Works as expected, listener is named
const testbutton = document.getElementById('kek');
const testListener = () => {
console.log('I show up only once');
testbutton.removeEventListener('click', testListener);
};
testbutton.addEventListener('click', testListener);
如果您不关心 Internet Explorer 支持,您可以使用 AbortController 以更优雅的方式删除匿名事件侦听器。将 signal
选项传递给 addEventListener()
并在要删除事件侦听器时调用 AbortController 的 abort()
方法:
var listenersRemover = new AbortController();
button.addEventListener('click', callback, {signal: listenersRemover.signal}));
listenersRemover.abort();
Note
:您应该“重新武装”中止控制器以对新的 addEventListener()
调用使用相同的信号。只需使用 new AbortController()
.
var listenersRemover = new AbortController();
const setEventListener = (buttons) => (event) => {
const buttonValue = event.target.value;
console.log('Eventlistener exists', buttonValue)
// buttons.forEach(button => button.removeEventListener('click', setEventListener));
};
const buttons = document.querySelectorAll('button');
buttons.forEach(button => button.addEventListener('click', setEventListener(buttons), {signal: listenersRemover.signal}));
// Works as expected, listener is named
const testbutton = document.getElementById('kek');
const testListener = () => {
console.log('I show up only once');
//testbutton.removeEventListener('click', testListener);
listenersRemover.abort();
};
testbutton.addEventListener('click', testListener, {signal: listenersRemover.signal});
<button value="1">press me</button>
<button value="2">press me</button>
<button id="kek">eventlistener removed on click</button>