使用jQuery进行事件捕获和冒泡

40

我是jQuery的新手,正在努力理解事件捕获和冒泡的概念。

我已经阅读了很多文章,但大多数都是描述JavaScript的事件传播。

假设我们有以下HTML代码:

<div id="outer">
    outer
    <div id="inner">
        inner
    </div>
</div>

捕获阶段是我们向下遍历DOM元素的阶段,而冒泡则是我们向上遍历的阶段。

在JavaScript中,您可以决定要按哪个方向遍历DOM(使用true或false参数):

element.addEventListener('click', doSomething, true) --> capture phase
element.addEventListener('click', doSomething, false) --> bubble phase

除了使用 JavaScript 的方法之外,jQuery 是否有类似的方法来指示应该按哪个方向执行操作?

另外,jQuery 是否使用默认阶段?例如冒泡?

因为我使用以下代码进行了测试:

css

<style>
    div {
        border: 1px solid green;
        width: 200px;
    }
</style>

jQuery

<script>
    $(document).ready(function(){
        $('div').click(function(){
            $(this).animate({'width':'+=10px'},{duration: 3000})
        });
    });
</script>

当我点击外部div时,只有该div会动画到较大的div。当我点击内部div时,两个div都会动画到较大的div。看起来默认的浏览器传播方法是冒泡。

如果我错了,请纠正我。


@adeneo 这个问题如何回答 jQuery 的作用?OP 似乎已经理解了冒泡和捕获的含义,他只是想知道它与 jQuery 有什么关系。 - Barmar
@Barmar - 我不确定,所以我没有关闭,我认为也许OP需要解释一下捕获是什么,因为它与jQuery没有任何关系,因为当调用addEventlistener时,jQuery硬编码'false',并且没有更改选项,因为通常不使用捕获。 - adeneo
5个回答

64

jQuery只使用事件冒泡。如果您想添加一个使用捕获模型的事件处理程序,您必须显式地使用addEventListener,并将第三个参数设置为true,就像您在问题中展示的那样。


6

事件冒泡会从最内部的元素开始执行,一直到最外层的元素。

事件捕获会从最外层的元素开始执行,一直到最内部的元素。

但是jQuery将使用事件冒泡。我们可以通过以下方式实现事件捕获:

$("body")[0].addEventListener('click', callback, true);

在addEventListener中的第三个参数将告诉浏览器是采用事件冒泡还是事件捕获。默认情况下它是false。
如果它是false,则会采用事件冒泡。如果它是true,则会采用事件捕获。

1
你也可以应用$("body").get(0),这与$("body")[0]的作用相同,它让你能够使用jQuery来操作JavaScript的本地特性。 - Muhammad Musavi

5

以下是一些误解:问题和答案中都认为浏览器只能捕获或冒泡事件。

实际上,每次单击时,浏览器都会按照捕获和冒泡的顺序执行。

jQuery 中是否有类似于 JavaScript 的方法来指定事件执行的方式?此外,jQuery 是否使用默认阶段?例如冒泡?

jQuery 没有事件阶段的概念,DOM 才有。并且 DOM 总是同时支持两个阶段。 但是 jQuery 只在冒泡阶段注册处理程序。没有途径可以使 jQuery 注册到捕获阶段,因此只能通过冒泡注册(使用 jQuery)。

我不知道是否错误,但是这个测试结果显示浏览器默认的事件传播方式是冒泡。

如果我可以说的话,你错了。当你点击外部 div 时,事件首先被捕获,直到达到外部 div,然后开始冒泡... 它不会深入到事件的实际目标之下。

如果你点击内部 div,则会在经过外部 div 后进行捕获,但是在那个阶段没有为其注册处理程序,然后它到达目标,在回溯(冒泡)时触发外部 div 处理程序。- 我没有运行你的代码,但很难确定哪个先发生(内部事件先发生)。

(注意:一旦到达目标,阶段实际上被称为“目标阶段”,处理程序会根据注册顺序独立调用,无论它们注册了哪个阶段的事件。)


1
每个“事件”都先通过“捕获”阶段,然后再通过“冒泡”阶段。
例如,当用户单击<a>时,所有使用“捕获”(addEventListener方法的第三个参数设置为true,不支持jQuery)绑定的事件处理程序从最外层的<html>开始,一直到链接。然后,“冒泡”阶段开始,所有使用“冒泡”(在jQuery中支持)的事件处理程序按相反的方式调用-从链接返回到<html>
您可以尝试在开发人员工具中激活此代码,并在网站上任意点击以查看效果。
document.querySelectorAll("*").forEach(it => {
   it.addEventListener("click", function() {console.log("capturing: ", it)}, true); 
   it.addEventListener("click", function() {console.log("bubbling: ", it)}, false); 
});

-1

事件在事件冒泡中被触发,作用于用户单击的元素上,除非我们在事件对象上调用.stopPropagation()方法,否则事件将一直向上冒泡到DOM。 默认情况下,Jquery中设置了事件冒泡,如果要使用捕获,则需要在.addEventListner中将参数设置为true。


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