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/
问题是:click
找到的元素上find()
事件设置为什么即使其子元素有stopPropagation()
或stopImmediatePropagation()
也会触发?
请阅读已接受的答案及其评论,以了解为何会发生这种情况。
答案 0 :(得分:2)
如果在第二个参数中指定"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
(窗口位于所有内容的顶部),但由于您没有处理程序,因此您不会发现{{1}有任何影响。
解释它的另一种方式是调用stopPropagation()
与执行相同:
$("body").on( "click", "li", fn );
答案 1 :(得分:0)
您正在使用委托事件注册来注册事件处理程序,它使用事件冒泡来注册事件处理程序意味着当事件发生在元素中时,它将被冒泡到所有祖先元素,直到它到达文档对象。
在您点击a
的情况下,它会触发元素a
的点击事件,然后它会传播到li
,然后传播到ul
单击处理程序注册它被触发,然后它到达body
,html
和最后到document
对象,在那里你注册了其他点击处理程序,这些也会在你停止传播的地方执行但是ul
附带的事件已经被解雇了。
与li
关联的body
处理程序未被触发,因为a
中的body
处理程序阻止了传播
答案 2 :(得分:0)
您正在使用委派的事件侦听器,因此事件处理程序将附加到委派的目标,而不是后代。
前三个事件绑定到body
元素,最后一个事件绑定到ul
元素,该元素是body
的子元素。因此,ul
元素上的处理程序将首先触发,因为事件尚未冒泡到body
。事件到达body
后,传播将停止(如果点击了a
标记)。