38
elemen.addEventListener('click',func,false);
elemen.addEventListener('click',func,false);

请问func点击后是否会被调用两次elemen

如果是...是否有解决方案来检查是否存在相同的事件侦听器elemen

4

2 回答 2

76

func不会在点击时被调用两次,不但请继续阅读以了解详细信息和“陷阱”。

addEventListener规范中:

如果使用相同的参数在EventListeners同一设备上注册了多个相同EventTarget的实例,则会丢弃重复的实例。它们不会导致EventListener被调用两次,并且由于它们被丢弃,因此不需要使用该removeEventListener方法将其删除。

(我的重点)

这是一个例子:

var target = document.getElementById("target");

target.addEventListener("click", foo, false);
target.addEventListener("click", foo, false);

function foo() {
  var p = document.createElement("p");
  p.innerHTML = "This only appears once per click, but we registered the handler twice.";
  document.body.appendChild(p);
}
<input type="button" id="target" value="Click Me">

不过,重要的是要注意,它必须是同一个函数,而不仅仅是一个做同样事情的函数。例如,在这里我将四个单独的函数连接到元素,所有这些函数都将被调用:

var target = document.getElementById("target");

var count;
for (count = 0; count < 4; ++count) {
  target.addEventListener("click", function() {
    var p = document.createElement("p");
    p.innerHTML = "This gets repeated.";
    document.body.appendChild(p);
  }, false);
}
<input type="button" id="target" value="Click Me">

这是因为在每次循环迭代中,都会创建一个不同的函数(即使代码相同)。

于 2012-04-28T14:17:27.597 回答
2

我只想补充@TJ Crowler 提供的出色答案。

我有一个特定的任务,要求我为同一个事件向 HTML 元素添加两次相同的回调。确实,第二个丢弃了第一个,但是:

如果多个相同的 EventListener 在同一个 EventTarget 上注册了相同的参数,则重复的实例将被丢弃。它们不会导致 EventListener 被调用两次,也不需要使用 removeEventListener() 方法手动删除。

但是请注意,当使用匿名函数作为处理程序时,此类侦听器将不相同,因为即使使用相同不变的源代码定义,匿名函数也不相同,只是重复调用,即使在循环中也是如此。

来源:https ://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Multiple_identical_event_listeners (截至 2020 年 2 月 5 日。)

因此,如果第二个 EventListener 将其处理程序作为匿名函数,它不会丢弃第一个。所以它只会被调用两次。

循环解决方案的替代方案。

于 2020-02-05T22:36:31.597 回答