使用 jQuery 捕获和冒泡

Posted

技术标签:

【中文标题】使用 jQuery 捕获和冒泡【英文标题】:Capturing and Bubbling using jQuery 【发布时间】:2014-08-26 11:11:08 【问题描述】:

我是 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。

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

如果我错了,请纠正我。

【问题讨论】:

@adeneo 这个问题如何解决 jQuery 的功能? OP 似乎明白什么是冒泡和捕获,他只是想知道它与 jQuery 的关系。 @Barmar - 不确定,这就是我没有关闭的原因,我想也许 OP 需要对捕获的解释进行解释,因为它与 jQuery 完全没有关系,因为jQuery 在调用 addEventlistener 时将其硬编码为“false”,并且无法更改它,因为通常从不使用捕获。 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

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

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

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

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

默认为假。

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

【讨论】:

您也可以应用 $("body").get(0) 它与 $("body")[0] 相同,它可以让您使用 jquery 来处理 javascript 原生功能。跨度> 【参考方案3】:

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

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

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

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

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

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

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

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

【讨论】:

【参考方案4】:

每个Event 都会先经过“捕获”阶段,然后再经过“冒泡”阶段。

例如,当用户单击&lt;a&gt; 时,所有使用“捕获”绑定的事件处理程序(addEventListener 方法中的第三个参数设置为true,在 jQuery 中不支持)从最外面的&lt;html&gt; all 开始调用通往链接的路。然后,“冒泡”阶段开始,所有使用“冒泡”(在 jQuery 中支持)的事件处理程序都以相反的方式调用 - 从链接返回到 &lt;html&gt;

您可以自行尝试,在开发人员工具中触发此代码,然后单击您网站上的任意位置。

document.querySelectorAll("*").forEach(it => 
   it.addEventListener("click", function() console.log("capturing: ", it), true); 
   it.addEventListener("click", function() console.log("bubbling: ", it), false); 
);

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于使用 jQuery 捕获和冒泡的主要内容,如果未能解决你的问题,请参考以下文章

JS事件冒泡和事件捕获

jQuery基础-事件

js之事件冒泡和事件捕获及其阻止详细介绍

使用 addEventListener 进行冒泡和捕获

js 事件捕获与事件冒泡例子

什么是事件冒泡和捕获?