【发布时间】:2016-08-04 17:18:50
【问题描述】:
当使用委托事件时,所有匹配的元素都会触发该事件,因为它会从目标中冒出。
基于https://learn.jquery.com/events/event-delegation/ 并参考下面的 HTML 和 JS,点击 div-4 会触发其所有祖先(div-one、div-2、div-3、body)上的点击事件,因为它会冒泡。我将事件处理程序放在主体上,选择:not(#div-three)
这可以在https://jsfiddle.net/bLw7ch50/1/ 中看到,例如,单击 div 4 会触发 3 个警报。对于 div-4、div-2 和 div-one。
我认为发生的事情是这样的:
- 点击
div-four,触发来自div-four的点击事件。 -
div-four事件气泡到div-three,来自div-three的点击事件触发。 -
div-four事件气泡到div-two,来自div-two的点击事件触发。 -
div-four事件气泡到div-one,来自div-one的点击事件触发。 -
div-four事件气泡到body,来自body的点击事件触发。事件处理程序运行。举报target:div-four|current:div-four。 -
div-three(从第 2 步开始)事件冒泡到body。不触发事件处理程序。 -
div-two(从第 3 步开始)事件冒泡到body。事件处理程序运行。举报target:div-four|current:div-two。 -
div-one(从第 4 步开始)事件冒泡到body。事件处理程序运行。举报target:div-four|current:div-one。
如果在事件处理程序中调用了event.stopPropagation(),div-four 事件将在第 5 步停止冒泡。(尽管在 body 上方没有任何冒泡。)但是,在步骤 2,3 中触发的事件, 4 应该仍然存在并冒泡,因此步骤 6、7、8 仍将继续。
但是,情况似乎并非如此。在下面的https://jsfiddle.net/bLw7ch50/ 中,取消注释event.stopPropagation() 后,只出现1 个警报,target:div-four|current:div-four。所以我可能在某个地方错了。我的理解有什么问题?
HTML:
<body>
<div id="div-one">
1st div
<div id="div-two">
2nd div
<div id="div-three">
3rd div
<div id="div-four">
4th div
</div>
</div>
</div>
</div>
<br/>
<br/>
<div id="output">
</div>
</body>
CSS:
div {
border: 1px solid;
}
Javascript(使用 jquery1.9.1)
$(document).ready(function() {
$("body").on("click", ":not(#div-three)", function(event) {
var event_target = $(event.target).attr("id");
var event_current = $(event.currentTarget).attr("id");
$("#output").append("target:" + event_target +
"|current:" + event_current + "<br/>");
alert("target:" + event_target +
"|current:" + event_current);
// Commented out in https://jsfiddle.net/bLw7ch50/1/, exists in https://jsfiddle.net/bLw7ch50
event.stopPropagation(); // When this line is here, all other events stop
});
});
【问题讨论】:
-
因为...要发生委托事件,该事件必须传播到委托目标...如果您在此过程中停止任何处理程序上的传播,它将不会传播。跨度>
-
..Umm 传播到
body后没有更多传播了吗?你是说事件再次传播到body? -
它只传播一次到文档,然后再次返回。它不会从中间的每个元素重新开始,只有一个事件。如果你停止它,它就会停止。
-
等一下,首先,“它只传播一次到文档,然后再返回”是什么意思?事件从文档到目标,然后备份不是吗?而且,如果只有 1 个事件,为什么没有
event.stopPropagation()它会触发 3 次? -
是的,与我所说的相反,:) 它触发了三次,因为符合事件条件的三个元素是委托目标的后代(并且在事件链中,或者你称之为. 原始目标和委托目标之间的元素。)
标签: javascript jquery events event-delegation