例如,
document.addEventListener('keyup',function(ev){
if(ev.ctrlKey)dosomething();
},false);
有没有办法删除匿名函数?
答案 0 :(得分:0)
您可以命名匿名函数并使用它来取消绑定
document.addEventListener('keyup',function handleKeyUp(ev){
document.removeEventListener(ev.type, handleKeyUp);
if(ev.ctrlKey)dosomething();
},false);
答案 1 :(得分:0)
您可以使用箭头功能调用函数并传递事件。
document.addEventListener('keyup',event => dosomething(event));
function dosomething(event){
console.log("Test 1");
event.currentTarget.removeEventListener(event.type, arguments.callee.caller);
}
/////////////////////////////////////
//OR
document.addEventListener('keyup', function(event){
console.log("Test 2");
event.currentTarget.removeEventListener(event.type, arguments.callee);
});

使用此实现还可以保留this
。
与函数表达式相比,箭头函数表达式具有更短的语法,并且不绑定它自己的this,arguments,super或new.target。箭头功能始终是匿名的。这些函数表达式最适合非方法函数,不能用作构造函数。
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
答案 2 :(得分:0)
在使用匿名功能时,无法从外部侦听器功能中删除该事件侦听器。虽然它可能在您的代码中显示为匿名,但它会被分配给某种变量,即使名称为listeners.keyup[3]
,它也会对其进行有效命名。
您可以使用arguments.callee
1 或从其调用的函数(如Zze's answer中所述)从事件侦听器本身中删除事件侦听器。 / p>
要使用EventTarget.removeEventListener()
删除侦听器,您需要引用正在侦听的实际函数。您需要执行以下操作之一:
命名函数。
document.addEventListener('keyup',handleKeyupEvent,false);
function handleKeyupEvent(ev) {
if(ev.ctrlKey) {
dosomething();
} else {
console.log('keyup event, no Ctrl key');
}
}
function dosomething(){
console.log('Ctrl key');
document.removeEventListener('keyup',handleKeyupEvent,false);
}

将其分配给变量,该变量实际上是命名它
变量不必只是一个仅引用函数的变量(例如handleKeyupEvent
)。例如,您可以将一个侦听器列表存储在Object或Array中(例如listeners.keyup[3]
)。当动态创建实际的侦听器功能时(例如,使用.bind()
),这可能是有利的。
handleKeyupEvent = function(ev) {
if(ev.ctrlKey) {
dosomething();
} else {
console.log('keyup event, no Ctrl key');
}
}
document.addEventListener('keyup',handleKeyupEvent,false);
function dosomething(){
console.log('Ctrl key');
document.removeEventListener('keyup',handleKeyupEvent,false);
}

使用arguments.callee
1
document.addEventListener('keyup',function(ev){
if(ev.ctrlKey) {
dosomething();
ev.currentTarget.removeEventListener(ev.type, arguments.callee,false);
} else {
console.log('keyup event, no Ctrl key');
}
},false);
function dosomething(){
console.log('Ctrl key');
}

从侦听器使用Function.caller
调用的函数访问它。
document.addEventListener('keyup',function(ev){
if(ev.ctrlKey) {
dosomething(ev);
} else {
console.log('keyup event, no Ctrl key');
}
},false);
function dosomething(ev){
console.log('Ctrl key');
ev.currentTarget.removeEventListener(ev.type, dosomething.caller,false);
}

以其他方式,存储对该函数的引用。
对于常规元素(即不是<document>
等),您可以有效地删除所有侦听器,但不能只删除一个。您可以充分操作DOM,例如删除该元素上的所有事件侦听器(或者创建元素的等效克隆)。最不具破坏性的是Node.cloneNode()
元素,然后将当前元素替换为克隆,同时将原始的所有子元素附加到克隆(从而保留子元素及其后代上存在的任何事件处理程序)。 / p>
1。 MDN has this to say about using arguments.callee
:
警告:5th edition of ECMAScript (ES5)禁止在strict mode中使用
arguments.callee()
。避免使用arguments.callee()
通过给函数表达式命名或使用函数声明,函数必须调用它自己。
基本上,最好只给函数一个名称,即使它在该函数表达式中只是有效:
document.addEventListener('keyup',function myFunctionName(ev){
//myFunctionName is only valid within the function. You should use this type of
// name instead of using arguments.callee.
if(ev.ctrlKey)dosomething();
},false);
答案 3 :(得分:0)
您可以自己为addEventListener
写一个小界面,如下所示:
function addEventListener(elt, event, fn) {
elt.addEventListener(event, fn);
return function() {
elt.removeEventListener(event, fn);
};
}
这将返回一个函数,可用于删除事件侦听器,无论传递什么函数。
要使用它:
var remove = addEventListener(body, 'click', () => alert('Hi Mom'));
remove();
要在触发后立即删除事件侦听器,您只需要:
function addEventListenerOnce(elt, event, fn) {
elt.addEventListener(event, function listener() {
fn(e);
elt.removeEventListener(elt, listener);
});
}
或者,您可以使用在某些浏览器中实现的新{once: true}
选项。