注册捕获阶段的事件监听器在冒泡之前未触发 - 为什么? [英] Event listeners registered for capturing phase not triggered before bubbling - why?

查看:172
本文介绍了注册捕获阶段的事件监听器在冒泡之前未触发 - 为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解在点击嵌套< div> 时触发事件处理程序的顺序是什么 - 我所看到的似乎有点不一致有记录的行为,所以我正在寻找一些帮助来理解它。

I'm trying to understand what determines the order in which event handlers are triggered when clicking a nested <div> - what I am seeing seems to be at odds with documented behaviour so I'm looking for a little help to understand it.

我有2个嵌套的div,我有2个事件处理程序连接到每个,一个用于捕获阶段,一个用于冒泡阶段:

I have 2 nested divs, and I have 2 event handlers attached to each, one for the capturing phase, and one for the bubbling phase:

<html>
    <head>
        <script>
            function setup(){
                var outer = document.getElementById('outer');
                outer.addEventListener('click', function(){console.log('outer false');}, false);
                outer.addEventListener('click', function(){console.log('outer true');}, true);

                var inner = document.getElementById('inner');
                inner.addEventListener('click', function(){console.log('inner false');}, false);
                inner.addEventListener('click', function(){console.log('inner true');}, true);
            }           
        </script>
        <style>
            div {
                border: 1px solid;
                padding: 1em;
            }
        </style>
    </head>
    <body onload="setup()">
        <div id="outer">
            <div id="inner">
                CLICK
            </div>
        </div>
    </body>
</html>

根据我读过的输出应该是:

outer true
inner true
inner false
outer false

但我实际看到的内容(在Chrome和Firefox上)是:

but what I actually see (on Chrome and Firefox) is:

outer true
inner false
inner true
outer false

任何人都可以解释这种差异吗?

Can anyone explain the discrepancy?

推荐答案

W3C事件流规范(即Chrome和Firefox实现的)是所有事件首先被捕获,直到它们到达目标元素,此时它们再次冒泡。但是,当事件流到达事件目标本身时,事件不再捕获或冒泡 - 它位于目标本身上。由于冒泡/捕获不适用,事件处理程序按照它们的注册顺序触发。尝试交换内部元素事件处理程序的顺序,您会发现它也会更改控制台输出的顺序。

W3C event flow spec (i.e., what Chrome and Firefox implement) is that all events are first captured until they reach the target element, at which point they bubble up again. However, when the event flow reaches the event target itself, the event is no longer capturing or bubbling--it's on the target itself. Because bubbling/capturing is not applicable, the event handlers fire in the order in which they are registered. Try swapping the order of your inner element event handlers, you'll find that it also changes the order of the console output.

jsFiddle示例: http://jsfiddle.net/RTfwd/1/

jsFiddle example: http://jsfiddle.net/RTfwd/1/

DOM事件规范的最新修订使这一点更加明确(http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html):

More recent revisions of the DOM Event spec make this point more clear (http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html):


冒泡阶段
一个事件可由其中一个处理的过程事件目标处理之后目标的祖先。有关更多详细信息,请参阅事件流上下文中的气泡阶段说明。

bubbling phase The process by which an event can be handled by one of the target's ancestors after being handled by the event target. See the description of the bubble phase in the context of event flow for more details.

捕获阶段处理事件的过程
中的一个目标的祖先在事件目标处理之前。请参阅
事件流程上下文中捕获阶段的描述
更多详情。

capture phase The process by which an event can be handled by one of the target's ancestors before being handled by the event target. See the description of the capture phase in the context of event flow for more details.

这篇关于注册捕获阶段的事件监听器在冒泡之前未触发 - 为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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