为何使用onclick绑定stopPropagation时子元素点击事件未触发?
为什么onclick属性里的stopPropagation会阻止jQuery委托事件触发?
这个问题的核心在于原生事件的执行时机和jQuery事件委托的工作机制之间的差异,我来给你拆解清楚:
关键原因
当你在<span>的onclick属性中调用event.stopPropagation()时,这个操作会在**事件传播的「目标阶段」**就直接阻止了事件继续向上冒泡。而jQuery通过$(document).on()绑定的委托事件,完全依赖事件冒泡到document节点时才会触发——事件都没机会冒泡到document,那些委托的处理程序自然就不会被执行。
两种场景的执行流程对比
场景1:在jQuery处理程序中调用stopPropagation(Child-2)
- 点击Child-2时,事件从目标元素开始向上冒泡,一路传到
document节点。 - jQuery监听到
document上的点击事件,检查目标元素是否匹配.abc选择器,匹配成功后执行对应的处理程序,弹出child click!。 - 随后调用
e.stopPropagation(),阻止事件继续冒泡(此时事件已经到达document,所以jQuery的委托处理已经完成,只是不会再往上传到window,同时父元素#parent的委托事件因为冒泡被阻止,不会触发)。
场景2:在onclick属性中调用stopPropagation(Child-1)
- 点击Child-1时,首先触发元素自身
onclick属性里的代码——这是在事件传播的目标阶段执行的,还没进入冒泡流程。 - 这里调用
event.stopPropagation(),直接掐断了事件的冒泡路径,事件根本不会向上传到父元素,更到不了document节点。 - jQuery绑定在
document上的委托事件,因为没接收到冒泡过来的事件,所以完全不会触发,自然就不会弹出child click!,父元素的处理程序也跟着没机会执行。
额外验证:如果把委托绑定在父元素而非document?
要是你把.abc的委托事件绑定在#parent上,而不是document:
$("#parent").on("click", ".abc", function (e) { alert("child click!"); e.stopPropagation(); });
这时候点击Child-1,onclick里的stopPropagation()还是会阻止事件冒泡到#parent,所以委托绑定在父元素的处理程序同样不会触发。只有当委托直接绑定在目标元素自身时(比如$(".abc").on("click", ...)),才会和onclick属性的处理程序一起执行,因为它们都是在目标阶段触发的。
总结
- 原生
onclick属性的处理程序在目标阶段执行,此时调用stopPropagation()会直接终止后续的冒泡流程。 - jQuery事件委托(绑定在父级/ document)完全依赖事件冒泡来触发,一旦冒泡被提前阻止,委托处理程序就无法被调用。
内容的提问来源于stack exchange,提问作者ctor
相关产品推荐
相关产品推荐

