jQuery事件冒泡

18
我想了解如何准确理解“事件冒泡”。它是指按照HTML代码层次结构往上走,还是有其他含义?
其次,我正在阅读一个示例,但无法理解最后一部分所说的:
“基于段落的点击处理程序监听点击事件,然后阻止其传播(向上冒泡)。”
这是什么意思?
7个回答

39

“冒泡”概念类似于,如果您有一个带有点击事件的子元素,而您不希望它触发父级的点击事件。您可以使用 event.stopPropagation()

event.stopPropagation() 基本上是说只将此点击事件应用于此子节点,不要告诉父容器任何内容,因为我不希望它们做出反应。

事件捕获:

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

事件冒泡:
               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

如果您使用的是live()delegate(),则需要return false;,但可能不起作用。请阅读以下引用。
根据jQuery文档
由于.live()方法处理事件时会将其传播到文档顶部,因此无法停止传播实时事件。同样,由.delegate()处理的事件将传播到它们委托的元素;在DOM树中任何下面的元素上绑定的事件处理程序将在调用委托的事件处理程序时已经执行。因此,这些处理程序可能通过调用event.stopPropagation()或返回false来防止委托处理程序触发。
过去,这是一个平台问题,Internet Explorer有一个冒泡模型,而Netscape更多地关注捕获(但两者都支持)。 W3C模型要求您能够选择您想要的模式。
我认为冒泡更受欢迎,因为正如所述,有些平台只支持冒泡...并且作为“默认”模式,这在某种程度上是有道理的。
您选择哪个取决于您正在做什么以及对您有意义的内容。
更多信息http://www.quirksmode.org/js/events_order.html

另一个很好的资源:http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/


1
所有这些时间,我甚至不知道有这样的东西存在。+1 让我学到了新东西! - Mrchief
2
你可能会发现这张图片(通过w3c的DOM Level 3 Events规范)很有用:http://i.imgur.com/qlV9Z.png - user1385191

12
return false;

使用 stopPropagation() 可以防止事件“冒泡”,用于阻止默认操作,例如勾选复选框、打开下拉列表、点击等。

如果要停止使用 .live() 绑定的处理程序后执行更多处理程序,则处理程序必须返回 false。调用 .stopPropagation() 无法实现此目的。

参考自 jQuery .live() 的注意事项.

原因 (感谢 @AlienWebguy): .live() 将事件绑定到文档上,因此在触发时已经没有其他地方可以冒泡。


@test,如果答案是false,则返回。 - Joe
根据jQuery文档中关于live的说明,@test,e.stopPropagation()是不够的。我确定它在Chrome或其他浏览器中可以工作,但如果你想要真正的跨浏览器支持,就需要返回false。这是直接从jQuery文档中摘取的。 - Joe
这对我很有帮助!由于某种原因,在我的特定情况下,e.preventDefault(); e.stopPropagation();并没有帮助我(尽管在大多数情况下似乎是有效的)。 - Ryan
1
stopPropagation()不与live()一起工作的原因是live()将事件绑定到document,因此在它触发时没有其他地方可以传播了。 - AlienWebguy
@Joe 很棒的答案,正是我在寻找的。在我的 .click 处理程序中加入 return false;,解决了我的问题。谢谢。 - Forged
显示剩余3条评论

2
它的意思是live()方法将事件处理程序附加到document元素,并检查事件的target以确定其来自哪里。如果目标与选择器匹配,则触发事件处理程序。所有这些都建立在冒泡事件系统的基础上。
在示例中,p元素上的单击处理程序是a元素的祖先,通过返回false取消了冒泡。然后document元素将永远不会接收事件,因此它不会触发事件处理程序。

我正试图表达这样的话,你比我先说了。 - karim79
完美...这正是我在寻找的...虽然第一段有点难以理解,但我想我必须多读几遍才能理解...但重点是,你确实按照我的问题真正地回答了。 - copenndthagen
我并非以英语为母语,所以有时我的句子难以理解... - Johnny5
嗯...当我说“有点难理解”时,我并不是指英语本身...有些概念很难解释...但你绝对以最好的方式解释了它...甚至可以超过任何英国人... 顺便说一句...我也不是以英语为母语的... - copenndthagen

1
在下面的示例中,它将点击事件附加到ID为“anchor”的锚点。这个锚点位于一个包含有点击事件的div中。如果我们点击这个锚点,就好像我们点击了包含的div一样。现在,如果我们想在这个锚点上执行一些操作,但不希望触发div的点击事件,我们可以停止事件冒泡,如下所示。
<div id="div">

<a href="google.com" id="anchor"></a>

</div>


$("#div").click(function(e){//On anchor click this event will not be fired as we have stop the event propagation in anchor click handler.

   //Do stuff here

});

$("#anchor").click(function(e){

   //Do stuff here

   //This line stops the event bubling and 
   //jquery has abstracted it in the event object to make it cross browser compatible.
   e.stopPropagation();
});

0

0

这两个链接提供了关于事件冒泡(以及常用的事件概念)的清晰详细解释。

http://jqfundamentals.com/chapter/events
http://www.mattlunn.me.uk/blog/2012/05/what-does-event-bubbling-mean/

来自第一个链接

事件将被触发到包含 a 元素的所有元素上,一直冒泡到 document

来自第二个链接

<div>
    <h1>
        <a href="#">
            <span>Hello</span>
        </a>
    </h1>
</div>

假设我们点击了这个,这会导致在该上触发一个点击事件;到目前为止还没有什么革命性的变化。然而,事件随后会向父元素(即
)传播(或冒泡),并在其上触发一个点击事件。这个过程会重复进行,直到文档元素。

现在让我们将所有这些放入DOM的上下文中。DOM是一棵树,每个元素都是DOM树中的一个节点。冒泡只是从节点(某个元素)遍历到根节点(文档)的过程(一直跟随你的父元素,直到无法再往上了)。

0

是的,事件会沿着树向上冒泡,如果任何元素有该事件的处理程序,它将被调用。 通过在其中一个元素的处理程序中添加return:false,可以防止事件冒泡。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接