多个addEventListener如何在JavaScript中工作? [英] How do multiple addEventListener work in JavaScript?

查看:145
本文介绍了多个addEventListener如何在JavaScript中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文档中有2个脚本

// my_script.js goes first
document.onclick = function() {
    alert("document clicked");
};

// other_script.js comes after
// this overrides the onclick of my script,
// and alert will NOT be fired
document.onclick = function() {
    return false;
};

为了确保我的点击事件不被其他脚本覆盖,我切换到 addEventListener

To make sure my click event does not get overridden by other script, I switched to addEventListener.

// my_script.js goes first
document.addEventListener("click", function() {
    alert("document clicked");
}, false);

// other_script.js comes after
document.addEventListener("click", function() {
    return false;
}, false);

现在我又得到了一个问题。由于第二个代码中的 return false 是在 alert 之后定义的,为什么它不会阻止调用警告?

Now I got another question. Since return false in the second code is defined after alert, how come it does not prevent alert from being called?

如果我希望我的脚本能够完全控制点击事件(比如忽略其他脚本中定义的事件,则一直返回false)该怎么办?

What if I want my script to get total control of click event (like return false all the time disregarding events defined in other scripts)?

推荐答案


如果我希望我的脚本能够完全控制点击事件(如同忽略其他脚本中定义的事件一直返回false) )?

What if I want my script to get total control of click event (like return false all the time disregarding events defined in other scripts)?

如果你可以先注册你的处理程序,那么你可以这样做,只要你使用的浏览器正确使用实现DOM3事件(除非它是IE8或更早版本,它可能会执行)。

If you can register your handler first, before they do, you can do that, provided the browser you're using correctly implements DOM3 events (which it probably does unless it's IE8 or earlier).

这里涉及到(至少)四件事:

There are (at least) four things involved here:


  1. 防止默认。

  1. Preventing the default.

停止传播到祖先元素。

停止相同 el上的其他处理程序被叫的事情。

Stopping other handlers on the same element from being called.

调用处理程序的顺序。

按顺序:

这是来自DOM0处理程序的 return false 。 (详情: 返回故事 。)DOM2和DOM3中的等价物是 preventDefault

This is what return false from a DOM0 handler does. (Details: The Story on Return False.) The equivalent in DOM2 and DOM3 is preventDefault:

document.addEventListener("click", function(e) {
    e.preventDefault();
}, false);

防止违约可能与你正在做的事情无关,但是因为你在使用在您的DOM0处理程序中返回false ,这会阻止默认值,我在此处将其包含在内以保证完整性。

Preventing the default may not be all that relevant to what you're doing, but since you were using return false in your DOM0 handler, and that prevents the default, I'm including it here for completeness.

DOM0处理程序无法执行此操作。 DOM2可以通过 stopPropagation

DOM0 handlers have no way to do this. DOM2 ones do, via stopPropagation:

document.addEventListener("click", function(e) {
    e.stopPropagation();
}, false);

stopPropagation 不会阻止其他处理程序在同一个元素被调用。从规范

But stopPropagation doesn't stop other handlers on that same element getting called. From the spec:


使用 stopPropagation 方法防止在事件流期间进一步传播事件。如果任何 EventListener 调用此方法,则事件将停止在树中传播。 该事件将在事件流程停止之前完成对当前 EventTarget 的所有侦听器的调度。

The stopPropagation method is used prevent further propagation of an event during event flow. If this method is called by any EventListener the event will cease propagating through the tree. The event will complete dispatch to all listeners on the current EventTarget before event flow stops.

(我的重点。)

当然,DOM0没有出现这种情况,因为没有同一元素上同一事件的其他处理程序。 : - )

Naturally, this didn't come up for DOM0, because there couldn't be other handlers for the same event on the same element. :-)

据我所知,在DOM2中没有办法做到这一点,但是DOM3给了我们 stopImmediatePropagation

As far as I'm aware, there's no way to do this in DOM2, but DOM3 gives us stopImmediatePropagation:

document.addEventListener("click", function(e) {
    e.stopImmediatePropagation();
}, false);

有些库提供此功能(即使在非DOM3系统,如IE8),处理程序通过图书馆,见下文。

Some libraries offer this feature (even on non-DOM3 systems like IE8) for handlers hooked up via the library, see below.

同样,不是与DOM0相关的东西,因为没有其他处理程序。

Again, not something that related to DOM0, because there couldn't be other handlers.

在DOM2中,规范显式表示不保证调用附加到元素的处理程序的顺序;但是DOM3改变了这一点,说处理程序按照它们注册的顺序被调用。

In DOM2, the specification explicitly says that the order in which the handlers attached to an element are called is not guaranteed; but DOM3 changes that, saying that handlers are called in the order in which they're registered.

首先,来自DOM2 第1.2.1节

First, from DOM2 Section 1.2.1:


虽然 EventTarget 上的所有 EventListeners 都可以保证被触发通过 EventTarget 收到的任何事件,没有规定他们将收到关于其他 EventListeners的事件的顺序 EventTarget 上的

Although all EventListeners on the EventTarget are guaranteed to be triggered by any event which is received by that EventTarget, no specification is made as to the order in which they will receive the event with regards to the other EventListeners on the EventTarget.

但这是取决于DOM3 第3.1节

But this is superceded by DOM3 Section 3.1:


接下来,实现必须确定当前目标的候选事件侦听器。这必须是已在当前目标上按其注册顺序注册的所有事件侦听器的列表。

Next, the implementation must determine the current target's candidate event listeners. This must be the list of all event listeners that have been registered on the current target in their order of registration.

(我的重点。)

如果您将事件与库连接,有些图书馆会保证订单。

Some libraries guarantee the order, provided you hook up the events with the library.

值得注意的是,在Microsoft的DOM2前身(例如, attachEvent )中,它与DOM3的顺序相反:处理程序以反向注册顺序调用。

It's also worth noting that in Microsoft's predecessor to DOM2 (e.g., attachEvent), it was the opposite of DOM3's order: The handlers were called in reverse order of registration.

所以将#3和#4放在一起,如果你可以先注册你的处理程序,它将首先被调用,你可以使用 stopImmediatePropagation 来防止其他处理程序被调用。如果浏览器正确实现DOM3。

So taking #3 and #4 together, if you can register your handler first, it will get called first, and you can use stopImmediatePropagation to prevent other handlers getting called. Provided the browser implements DOM3 correctly.

所有这些(包括IE8及更早版本甚至不实现DOM2的事实事件,更不用说DOM3)是人们使用像jQuery这样的库的一个原因,其中一些确实保证了顺序(只要一切都通过相关的库连接他们的处理程序)并提供了阻止同一元素上的其他处理程序的方法被叫。 (例如,使用jQuery,顺序是它们附加的顺序,您可以使用 stopImmediatePropagation 来停止对其他处理程序的调用。但我不是试图在这里卖jQuery,只是解释一些lib提供的功能比基本的DOM更多。)

All of this (including the fact that IE8 and earlier don't even implement DOM2 events, much less DOM3) is one reason people use libraries like jQuery, some of which do guarantee the order (as long as everything is hooking up their handlers via the library in question) and offer ways to stop even other handlers on the same element getting called. (With jQuery, for instance, the order is the order in which they were attached, and you can use stopImmediatePropagation to stop calls to other handlers. But I'm not trying to sell jQuery here, just explaining that some libs offer more functionality than the basic DOM stuff.)

这篇关于多个addEventListener如何在JavaScript中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆