使用 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
都会先经过“捕获”阶段,然后再经过“冒泡”阶段。
例如,当用户单击<a>
时,所有使用“捕获”绑定的事件处理程序(addEventListener
方法中的第三个参数设置为true
,在 jQuery 中不支持)从最外面的<html>
all 开始调用通往链接的路。然后,“冒泡”阶段开始,所有使用“冒泡”(在 jQuery 中支持)的事件处理程序都以相反的方式调用 - 从链接返回到 <html>
。
您可以自行尝试,在开发人员工具中触发此代码,然后单击您网站上的任意位置。
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 捕获和冒泡的主要内容,如果未能解决你的问题,请参考以下文章