如何在JS严格模式下删除当前的eventListener(没有被调用者)

时间:2017-04-21 13:37:29

标签: javascript event-listener strict-mode

问题:事件侦听器想要从目标侦听器列表中删除自己。 监听器可以是匿名函数和/或动态生成(闭包或绑定)

这是一个解决方案(在“模式严格”中不起作用): (例如“点击”事件)

function(ev){
   // .... some stuff
   ev.target.removeEventListener("click",arguments.callee);
}

但这在ES5严格模式下无效。

问题:还有另一种解决方案吗?

4 个答案:

答案 0 :(得分:1)

只需命名 - 即使对于函数表达式也是如此。

… function myListener(ev){
   // … some stuff
   ev.target.removeEventListener("click", myListener);
} …

答案 1 :(得分:0)

当您通过addEventListener添加事件侦听器时,您可以通过命名函数执行此操作,以便您有一个引用。

答案 2 :(得分:0)

感谢您的回答。

例如,使用闭包模式时,命名函数是一种解决方案。 但不适用于有界函数: 函数名称引用原始函数,而不是有界实例。

一些例子:

function listener(s,ev){
  "use strict";
  if (ev.target.value == s){
    console.log("<bounded> I found " + s+ ", Bye !");
    // Doesn't work : listener references original (not bounded) function
    ev.target.removeEventListener(ev.type, listener);
    // Who am I ?? ;-)
  } else {
    console.log("<bounded> still waiting for " +s + " " + new Date());
  }
}
window.addEventListener('load', function(){
  i = document.querySelector('input');
  i.addEventListener("change",listener.bind(i,"abc"));
  i.addEventListener("change",listener.bind(i,"def"));
});

我写了这个丑陋的解决方法:

function autoRefBind(f, ...args){
  var o = {};
  o.me = f.bind(o,...args);
  return o.me;
}
function listener(s,ev){
  "use strict";
  if (ev.target.value == s){
    console.log("<bounded> I found " + s+ ", Bye !");
    ev.target.removeEventListener(ev.type, this.me);
  } else {
    console.log("<bounded> still waiting for " +s + " " + new Date());
  }
}
window.addEventListener('load', function(){
  i = document.querySelector('input');
  i.addEventListener("change",autoRefBind(listener,"abc"));
  i.addEventListener("change",autoRefBind(listener,"def"));
});

但它非常......丑陋:'这'必须是这个“愚蠢”的对象{me:}

答案 3 :(得分:0)

事件绑定适用于每个事件名称的函数(处理程序)实例的注册!

基本上,当您调用addEventListener时,您将定义在触发给定命名事件时要调用的函数地址。

因为您使用的是bind,所以您可以使用bind返回新功能(参见bind文档)。

但是,根据我对您的代码的理解,您尝试运行一次事件处理程序(并从事件注册列表中自行分离)。

如果是这样,为什么不告诉addEventListener只运行一次小时处理程序(参见addEventListener文档)? 这是一个更简单的代码:

function listener(s,ev){
  "use strict";
  console.log("executing listener once with ", s)
}
window.addEventListener('load', function(){
  i = document.querySelector('input');
  i.addEventListener("change",listener.bind(i,"abc"), {once:true});
  i.addEventListener("change",listener.bind(i,"def"), {once:true});
});

您可以在此处进行测试:https://jsfiddle.net/rptsrfLz/