HTML:
<ul>
<li>
<a href="http://wp.pl">wp.pl</a>
</li>
</ul>
Javascript:
$(document).ready(function() {
$body = $('body');
$body.on('click', 'a', function(event) {
event.preventDefault();
event.stopPropagation();
/**
* Causes the "This also..." never shows, but "Why is..." still appears
*/
//event.stopImmediatePropagation();
alert('Should be seen always');
});
$body.on('click', 'a', function(event) {
alert('This also should be seen - same level as "a"');
});
$body.on('click', 'li', function() {
alert('This never shows - and that is ok - because is under "a"');
});
$body.find('ul').on('click', 'li', function() {
alert('Why is this shown?');
});
});
在这里摆弄:http://jsfiddle.net/g3PEr/1/
问题是:为什么在 find()
找到的元素上设置的 click
事件即使在其子元素具有 stopPropagation()
或stopImmediatePropagation()
?
请阅读已接受的答案及其评论,以了解为什么会发生这种情况。
最佳答案
在第二个参数中指定 "a"
或 "li"
并不重要 - 事件处理程序附加到 "body"
。选择器唯一要做的就是充当过滤器。当传播路径上没有任何元素与过滤器 "a"
匹配时,不会触发事件处理程序。就是这样。
因此,请将您的代码视为:
$body.on('click', function(event) {
event.preventDefault();
event.stopPropagation();
});
$body.on('click', function(event) {
});
$body.on('click', function() {
});
$("ul").on('click', function() {
});
由于冒泡从底部开始,因此首先触发 "ul"
处理程序。然后是主体处理程序,它们按照事件附加的顺序触发,因为它们都在主体上。
.stopImmediatePropagation()
可用于停止传播到同一级别以及任何更高级别的处理程序。
"body"
的上层仍然是 document
和 window
(窗口位于所有内容的顶部),但是因为你有那里没有处理程序,您不会观察到 stopPropagation()
有任何效果。
另一种解释方式是调用 $("body").on( "click", "li", fn );
与执行相同:
$("body").on( "click", function(e) {
var currentTarget = $(e.target).closest("li");
if( currentTarget.size() > 0 ) {
e.currentTarget = currentTarget;
fn.call(currentTarget, e);
}
});
关于jQuery:当底层元素使用 "event.stopPropagation()"设置单击事件时了解 "find()",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18192377/