JavaScript移除事件监听器

3
以下代码是否在销毁元素之前实际上删除了事件? 我无法在DOM检查器中找出附加的函数以及它们在运行以下代码后是否被删除:
el.addEventListener('click', function attachFunction (a, b) {
    console.log(a);
    console.log(b);
}, false);

el.removeEventListener('click', attachFunction, false);

2
它不会移除事件处理程序,因为在你尝试将其移除的范围中未定义attachFunction,所以它可能会产生错误。 - adeneo
4个回答

2
不,按照现有的情况,你的代码将无法工作。
请注意:要删除事件处理程序,使用 addEventListener() 方法指定的函数必须是外部函数。
(抱歉,但有时 w3fools 确实提供了你想要的内容) - 来自 W3Schools w3fools 因此,你需要这样做:
function attachFunction(a, b){
  console.log(a);
  console.log(b);
}

el.addEventListener('click', attachFunction, false);

el.removeEventListener('click', attachFunction, false);

这将按预期工作。
如果您想将某些参数传递给您的函数attachFunction,则需要使用另一个函数:
function attachFunction(a, b){
  console.log(a);
  console.log(b);
}

function linkFunction(){
  attachFunction(a, b); // a and b can be replaced with anything you want
}

el.addEventListener('click', linkFunction, false);

el.removeEventListener('click', linkFunction, false);

但是参数呢? - poashoas
如何在 addEventListener 中传递参数? - poashoas
抱歉,我不明白; 他们是什么意思?如果您告诉我应该设置为什么,我可以修复它,但目前我的参数与您的相同。 - theonlygusti
我的意思是:el.addEventListener('click', attachFunction(a, b), false); - poashoas
1
@LorenShqipognja 是的,完全正确。但要注意术语,应该是:“函数参数数组中的第一个项目始终是事件对象。” - theonlygusti
显示剩余6条评论

1
如果您想要能够移除使用addEventListener添加的事件监听器,请将其定义为addEventListener()调用的外部内容:
function attachFunction (a, b) {
    console.log(a);
    console.log(b);
}

然后:
el.addEventListener("click", attachFunction);

然后你的.removeEventListener()就可以工作了。

0

function foo(whatever) 的语法在运行时之前就被评估了,因此我认为你的代码不是有效的语法,也不会有预期的行为。你最好使用匿名函数,像这样:

var attachFunction = function(a, b) {
    console.log(a);
    console.log(b);
}
el.addEventListener('click', attachFunction, false);
el.removeEventListener('click', attachFunction, false);

请注意,事件监听器(此处为attachFunction)只能具有单个参数,即事件对象。

“在运行时之前进行评估”-- 我非常确定这不是真的。 - starwed
它是有效的;像那样的函数实例化表达式可以有名称,虽然语义与函数声明语句不同。 - Pointy

0

function 关键字有两种用法:作为 函数声明表达式。这里有一个关于它们之间差异的讨论 链接,但我会尝试涵盖相关部分。

当作为语句使用时(如下所示),函数名称将在语句所在的范围内有效:

function hi(){ 
    console.log(typeof hi); // "function"
}
console.log(typeof hi); // "function"

但是当函数名作为表达式使用时,函数名仅在函数体内有效:

var greetings = function hi(){ 
    console.log(typeof hi); // "function"
}
console.log(typeof hi); // "undefined"
console.log(typeof greetings); // "undefined

所以你初始示例中的作用域问题在于,因为你将其用作表达式,当你尝试解除绑定时,名称attachFunction将未定义。

(我认为你也对参数如何传递给事件处理程序有些困惑,但这是一个单独的问题。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接