【问题标题】:How do you remove an event listener that uses an anonymous function for passing parameters?如何删除使用匿名函数传递参数的事件侦听器?
【发布时间】:2019-04-21 21:32:09
【问题描述】:

提前道歉,因为我进行了一些搜索,这似乎是一个相当普遍的问题,但我找到的答案都没有完全满足我的需求。我能找到的最接近的是How do I add and remove an event listener using a function with parameters?,但那里的答案涉及 JQuery,我正试图找到一种仅在 JS 中执行此操作的方法。

我正在使用匿名函数通过事件触发器传递参数,我认为这是正确的方法。如果 temp 是由一些基于添加事件时的状态的计算定义的,我想添加监听器如下:

item.addEventListener("click", function(){myOnClickFunction(temp)});

但是,如果满足某些条件,我希望能够动态删除事件。

item.removeEventListener("click", function(){myOnClickFunction(temp)});

这不起作用,因为内联函数是匿名的,并且不能被引用以匹配事件侦听器(加上 temp 可能无论如何都不同)。由于 temp 是在触发时计算的,因此我无法在匿名函数之外存储引用,如下所示:

var listener = function() {
  var temp = calculate(arg1, arg2, event);
  myFunction(temp);
};
window.addEventListener('click', listener, false);

这样我以后可以打电话:

window.removeEventListener('click', listener, false);


myOnClickEvent(temp){
  //My code and calculations here
  document.removeEventListener("keypress", arguments.callee);
}

也不起作用,尽管我对该方法应该如何工作不太自信。

如何动态删除此功能?在某些情况下,我也许可以重构我的代码,以便所有需要传递的变量都全局存储并不断重写,但这听起来像是乱码。另外,在某些情况下,触发事件是需要传递的参数之一,所以我认为我无法做到这一点。有什么想法吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您可以创建一个对象,其属性是temp 值,其值是绑定到tempmyOnClickFunction。例如:

    const boundFns = {};
    // acquire temp somehow
    const boundFn = () => myOnClickFunction(temp);
    boundFns[temp] = boundFn;
    item.addEventListener("click", boundFn);
    

    然后,当您需要移除监听器时,检索适当的绑定函数:

    item.removeEventListener("click", boundFns[temp]);
    

    如果temp可能被多次使用,请先检查boundFns中是否存在:

    const boundFns = {};
    // acquire temp somehow
    if (!boundFns[temp]) {
      boundFns[temp] = () => myOnClickFunction(temp);
    }
    const boundFn = boundFns[temp];
    boundFns[temp] = boundFn;
    item.addEventListener("click", boundFn);
    

    如果 temp 不能可靠地用作唯一的对象键(例如,如果它是 HTMLElement),则可以使用 Map 代替,它类似于对象,但其键可以是 任何东西,而不仅仅是字符串:

    const boundFns = new Map();
    boundFns.set(temp, boundFn);
    // ...
    item.removeEventListener("click", boundFns.get(temp));
    

    【讨论】:

    • 好的。那么,如果我需要在 myOnClickFunction 中获取事件,那将如何工作?假设这是一个按键事件而不是点击事件,我需要能够从中检索 event.key 。 BoundFn 无法访问事件对象,因为它不在事件链中。
    • boundFn一个参数,然后用这个参数调用myOnClickFunction。例如(event) => myOnClickFunction(event, temp); 或类似的东西
    • 直到事件将传递给被调用函数而无需显式传递。在这和你的答案之间,我想我已经准备好了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    相关资源
    最近更新 更多