如果我希望我的脚本完全控制点击事件(比如始终返回 false,而忽略其他脚本中定义的事件)怎么办?
如果您可以先注册您的处理程序,在他们这样做之前,您可以这样做,前提是您使用的浏览器正确实现了 DOM3 事件(除非它是 IE8 或更早版本,否则它可能会这样做)。
这里(至少)涉及四件事:
防止默认。
停止传播到祖先元素。
停止调用同一元素上的其他处理程序。
调用处理程序的顺序。
为了:
1.防止违约
这就是return false
DOM0 处理程序所做的。(详情:关于 Return False 的故事。) DOM2 和 DOM3 中的等价物是preventDefault
:
document.addEventListener("click", function(e) {
e.preventDefault();
}, false);
防止默认值可能与您正在做的事情并不完全相关,但由于您return false
在 DOM0 处理程序中使用,并且这会阻止默认值,因此我将其包含在此处以保持完整性。
2.停止传播到祖先元素
DOM0 处理程序无法做到这一点。DOM2 通过stopPropagation
:
document.addEventListener("click", function(e) {
e.stopPropagation();
}, false);
但stopPropagation
不会阻止调用同一元素上的其他处理程序。从规格:
该stopPropagation
方法用于在事件流期间防止事件的进一步传播。如果此方法被任何人调用,EventListener
则事件将停止在树中传播。在事件流停止之前,该事件将完成对当前所有侦听器的分派。EventTarget
(我的重点。)
3. 停止调用同一元素上的其他处理程序
自然,这不会出现在 DOM0 上,因为对于同一元素上的同一事件,不可能有其他处理程序。:-)
据我所知,在 DOM2 中没有办法做到这一点,但 DOM3 给了我们stopImmediatePropagation
:
document.addEventListener("click", function(e) {
e.stopImmediatePropagation();
}, false);
一些库为通过库连接的处理程序提供此功能(甚至在 IE8 等非 DOM3 系统上),见下文。
4. 调用处理程序的顺序
同样,与 DOM0 无关,因为不可能有其他处理程序。
在 DOM2 中,规范明确指出,附加到元素的处理程序被调用的顺序并不能保证。但是 DOM3 改变了这一点,说处理程序按照它们注册的顺序被调用。
首先,来自 DOM2第 1.2.1 节:
尽管EventListeners
上的所有内容EventTarget
都保证由其接收到的任何事件触发EventTarget
,但没有指定它们接收事件相对于 上的其他事件的EventListeners
顺序EventTarget
。
但这被 DOM3第 3.1 节取代:
接下来,实现必须确定当前目标的候选事件侦听器。这必须是按注册顺序在当前目标上注册的所有事件侦听器的列表。
(我的重点。)
一些库保证顺序,前提是您将事件与库挂钩。
还值得注意的是,在微软的 DOM2 前身(例如attachEvent
)中,它与 DOM3 的顺序相反:处理程序以注册的相反顺序调用。
所以把#3和#4放在一起,如果你可以先注册你的处理程序,它将首先被调用,你可以stopImmediatePropagation
用来防止其他处理程序被调用。前提是浏览器正确实现了 DOM3。
所有这一切(包括 IE8 和更早版本甚至不实现 DOM2 事件,更不用说 DOM3)是人们使用像 jQuery 这样的库的原因之一,其中一些确实保证了顺序(只要所有东西都通过有问题的库)并提供方法来阻止同一元素上的其他处理程序被调用。(例如,对于 jQuery,顺序是它们附加的顺序,您可以使用它stopImmediatePropagation
来停止对其他处理程序的调用。但我并不是想在这里出售 jQuery,只是解释一些库提供的功能比基本的 DOM 东西。)