JavaScript 中默认的事件顺序是什么?自上而下还是自下而上?

pho*_*nix 5 javascript event-bubbling dom-events

可能的重复:
什么是事件冒泡和捕获

我刚刚了解到,在 JS 中我们有两种事件类型:Capture 和 Bubble。eventListener泡泡可以用来避免所有孩子都需要依附;相反,仅将侦听器附加到父级并让它检查目标。听起来很酷。我尝试了这个例子:

<div id="parent-list">
    <span>span1</span>
    <span class='target'>span2</span>
    <span>span3</span>
    <span>span4</span>
</div>

<script type="text/javascript">
document.getElementById('parent-list').addEventListener('click',function(e){
    if( e.target && e.target.nodeName=='SPAN' ){
        var classes = e.target.className.split(' ');
        for(var i=0; i<classes.length; ++i){
            if( classes[i]=='target' ){
                alert('Bingo! you hit the target.');
            }
        }
    }
});
</script>
Run Code Online (Sandbox Code Playgroud)

但我还没有将任何侦听器附加到子跨度上。然而他们身上发生的事件却正在冒泡!那么冒泡是JS中默认的事件顺序吗?那么什么情况下会使用捕获(自上而下)呢?

Nor*_*ard 4

假设您有如下所示的 html:

<div id="grandparent">
    <div id="parent">
        <button id="target"></button>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

JS 看起来像这样:

function sayGrandpa (evt) { console.log("Grandpa"); }
function sayClicked (evt) { console.log("Clicked"); }

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

grandparent.addEventListener("click", sayGrandpa, false);
target.addEventListener("click", sayClicked, false);
Run Code Online (Sandbox Code Playgroud)

Bubbling vs Capture 实际上与您的假设没有任何关系,在这两种情况下(在符合 W3C 的浏览器上),您可以使用事件侦听器附加到父级,以侦听触发的事件一个孩子。

不同之处在于,冒泡假设事件链从目标开始,并通过父级链向上返回,就像一枚炸弹在零地引爆,并向外发出冲击波。

window捕获从(或)开始<html>,并向下到达目标元素。

因此,当您使用冒泡(更像是波纹)时,直接在元素上设置的任何函数都会首先发生,并且附加到祖先的任何委托函数都会在波纹返回链时发生。

当您使用捕获时,附加到祖先的任何委托函数都会在元素上发生事件之前发生。
因此该grandparent元素比之前知道一次点击target

因此,当你问事情发生的顺序时,事情就很明显了:

当您设置捕获grandparent的事件并设置冒泡的第二个事件,并设置其中任一事件时,顺序将是:grandparenttarget

captured grandparent target bubbled grandparent

那么什么时候让祖先知道在实际单击按钮之前发生的单击是有益的呢?
好问题!

我相信有人能想到一些东西,不仅仅是通过隐藏他们应该点击的东西来让人们痛苦的真正愚蠢的方式。

但道德是你必须明确要求它(设置.addEventListenerto的第三个参数true)。
此外,oldIE 和其他浏览器根本不支持捕获。

这并不是真正应该普遍使用的东西。