【问题标题】:What is the default event order in JavaScript? Top-down or Bottom-up? [duplicate]JavaScript 中的默认事件顺序是什么?自上而下还是自下而上? [复制]
【发布时间】:2012-10-26 21:36:18
【问题描述】:

可能重复:
What is event bubbling and capturing

我刚刚了解到,在 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>

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

【问题讨论】:

  • 不是直接重复,但应该回答您关于事件传播顺序的问题。
  • @FabricioMatte 我的问题是关于默认事件排序;不是他们。我在那篇文章中找不到类似的东西。如果我错了,请纠正我。
  • 冒泡(从最里面到最外面)是所有现代浏览器的默认设置,并且被 jQuery 使用。捕获(从最外到最内)不像跨浏览器,而且大多是旧的 IE 专有 AFAIK。
  • @FabrícioMatté 捕获实际上 被 ghettoIE根本 支持,而 W3C 要求与两者兼容。 ghettoIE 做对了其中之一,以及基于边框的 CSS 框大小调整,而不是仅内容。
  • @Norguard 是的,你是对的。我不得不重新阅读一些关于默认事件传播顺序的文章。 =]

标签: javascript dom-events event-bubbling


【解决方案1】:

想象一下你的 html 看起来像这样:

<div id="grandparent">
    <div id="parent">
        <button id="target"></button>
    </div>
</div>

而 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);

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

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

捕获从window(或&lt;html&gt;)开始,一直到目标元素。

所以当你使用冒泡(更像是涟漪)时,任何在元素上直接设置的函数都会首先发生,任何委托与祖先相关的功能,随着涟漪回到链条上而发生。

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

所以当你问事情发生的顺序时,事情很明显:

当您在grandparent 上设置一个捕获 事件并在grandparent 上设置第二个事件冒泡,然后在target 上设置一个事件,或者,顺序是:

captured grandparent target bubbled grandparent

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

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

但道德是你明确要求它(将.addEventListener的第三个参数设置为true)。
此外,oldIE 等根本不支持捕获。

这不是一般应该使用的东西。

【讨论】:

    【解决方案2】:

    默认事件顺序是特定于浏览器的

    事件捕获:外部元素的事件处理程序首先触发,内部元素的事件处理程序最后触发。

    事件冒泡:内部元素的事件处理程序首先触发,外部元素的事件处理程序最后触发。

    这两个事件顺序是完全相反的。 Explorer 仅支持 事件冒泡Mozilla、Opera 7 和 Konqueror 都支持。年长者 Opera 和 iCab 都不支持。

    在 Microsoft 模型中,您必须将事件的 cancelBubble 属性设置为 true。

    window.event.cancelBubble = true

    在 W3C 模型中,您必须调用事件的 stopPropagation() 方法。

    e.stopPropagation()

    function doSomething(e)
    {
        if (!e) var e = window.event;
        e.cancelBubble = true;
        if (e.stopPropagation) e.stopPropagation();
    }
    

    http://www.quirksmode.org/js/events_order.html

    【讨论】:

    • +1 你在“默认事件顺序是特定于浏览器的”中找到了我。
    • @Teeg:也有人说:IE 不符合 W3,再次:-)
    猜你喜欢
    • 1970-01-01
    • 2020-03-08
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2021-10-16
    • 2021-10-25
    • 2021-05-08
    相关资源
    最近更新 更多