38

我是 jQuery 新手,我正在尝试理解捕获和冒泡的概念。

我读过很多文章,但大多数都描述了 Javascript 的事件传播。

假设我们有以下 HTML 代码:

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

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

在 Javascript 中,您可以决定遵循哪种方式(使用 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。

不知道是不是我记错了,不过这个测试显示浏览器默认的传播方式是冒泡的。

如果我错了,请纠正我。

4

5 回答 5

60

jQuery 只使用事件冒泡。如果要添加使用捕获模型的事件处理程序,则必须使用 显式执行此操作,并使用问题中显示addEventListener的第三个参数true

于 2014-07-05T11:28:05.463 回答
6

事件冒泡将从最里面的元素开始执行到最外面的元素。

事件捕获将从外部元素开始执行到最里面的元素。

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

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

addEventListener 中的第三个参数将告诉浏览器是采用事件冒泡还是事件捕获。

默认情况下它是假的。

如果它是假的,那么它将采取事件冒泡。如果是真的,那么它将进行事件捕获。

于 2018-04-03T10:31:52.050 回答
5

问题和答案存在以下误解:浏览器要么捕获要么冒泡。

事实是:浏览器总是在每次点击时都按顺序捕获和冒泡。

除了 JavaScript 方式之外,jQuery 是否有类似的东西来表示遵循哪种方式?jQuery 也使用默认阶段吗?例如泡沫?

jQuery 没有事件阶段。DOM 有。并且 DOM 总是两者兼而有之。但是 jQuery 只将处理程序注册到冒泡阶段。没有 jQuery 方法可以注册到捕获阶段,所以气泡注册不是默认的,它是唯一的方法(使用 jQuery)。

不知道是不是我记错了,不过这个测试显示浏览器默认的传播方式是冒泡的。

你错了,如果我可以说的话。当您单击外部 div 时,会发生捕获,直到它到达外部 div,然后冒泡......它不会比事件的实际目标更深。

如果单击内部 div,捕获通过外部 div,但没有为该阶段注册处理程序,然后它到达目标,并在返回(冒泡)的路上触发外部 div 处理程序。-我没有运行您的代码,但很难判断哪个先发生(内部是第一个)。

(注意:一旦达到目标,该阶段实际上称为“目标阶段”,并且处理程序的调用与它们注册的阶段无关(按注册顺序,顺便说一句)。)

于 2020-04-11T11:12:28.183 回答
0

每个Event人都首先经历“捕获”阶段,然后经历“冒泡”阶段。

例如,当用户单击 时<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); 
});
于 2022-01-31T14:31:53.110 回答
-2

该事件在用户单击的元素上的事件冒泡中触发,除非我们在事件对象上调用 .stopPropagation() ,否则该事件将在 DOM 上一路触发。默认是在 Jquery 中设置的事件冒泡,以便使用 Capture ypu 需要在 .addEventListner 中将参数设置为 true

于 2019-12-16T18:59:00.297 回答