【发布时间】:2019-04-15 09:36:48
【问题描述】:
多年来,我在尝试删除 JavaScript 中的事件侦听器时遇到了问题。通常我必须创建一个独立的函数作为处理程序。但这只是草率,尤其是在添加箭头功能的情况下,只是一种痛苦。
我不追求 ONCE 解决方案。无论如何定义回调,这都需要在所有情况下工作。这需要是原始 JS,以便任何人都可以使用它。
以下代码运行良好,因为函数clickHandler 是一个独特的函数,addEventListener 和removeEventListener 都可以使用:
此示例已更新以显示我过去遇到的问题
const btnTest = document.getElementById('test');
let rel = null;
function clickHandler() {
console.info('Clicked on test');
}
function add() {
if (rel === null) {
rel = btnTest.addEventListener('click', clickHandler);
}
}
function remove() {
btnTest.removeEventListener('click', clickHandler);
}
[...document.querySelectorAll('[cmd]')].forEach(
el => {
const cmd = el.getAttribute('cmd');
if (typeof window[cmd] === 'function') {
el.addEventListener('click', window[cmd]);
}
}
);
<button cmd="add">Add</button>
<button cmd="remove">Remove</button>
<button id="test">Test</button>
你以前可以用arguments.callee做到这一点:
var el = document.querySelector('#myButton');
el.addEventListener('click', function () {
console.log('clicked');
el.removeEventListener('click', arguments.callee); //<-- will not work
});
<button id="myButton">Click</button>
但是使用箭头函数不起作用:
var el = document.querySelector('#myButton');
el.addEventListener('click', () => {
console.log('clicked');
el.removeEventListener('click', arguments.callee); //<-- will not work
});
<button id="myButton">Click</button>
有没有更好的办法??
更新
正如@Jonas Wilms 所说,这种方式可行:
var el = document.querySelector('#myButton');
el.addEventListener('click', function handler() {
console.log('clicked');
el.removeEventListener('click', handler); //<-- will work
});
<button id="myButton">Click</button>
除非你需要使用绑定:
var obj = {
setup() {
var el = document.querySelector('#myButton');
el.addEventListener('click', (function handler() {
console.log('clicked', Object.keys(this));
el.removeEventListener('click', handler); //<-- will work
}).bind(this));
}
}
obj.setup();
<button id="myButton">Click</button>
问题在于向addEventListener 函数提供事件处理程序的方法太多,如果在重构中传递函数的方式发生变化,您的代码可能会中断。
【问题讨论】:
-
或者你只使用 jQuerys
$(sth).once("click", ...)...
标签: javascript ecmascript-6 ecmascript-2017