jQuery:当底层元素使用“find()”设置click事件时,理解“event.stopPropagation()”

时间:2013-08-12 16:46:47

标签: jquery event-bubbling stoppropagation

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()也会触发?


请阅读已接受的答案及其评论,以了解为何会发生这种情况。

3 个答案:

答案 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"的上层仍然是documentwindow(窗口位于所有内容的顶部),但由于您没有处理程序,因此您不会发现{{1}有任何影响。

解释它的另一种方式是调用stopPropagation()与执行相同:

$("body").on( "click", "li", fn );

答案 1 :(得分:0)

您正在使用委托事件注册来注册事件处理程序,它使用事件冒泡来注册事件处理程序意味着当事件发生在元素中时,它将被冒泡到所有祖先元素,直到它到达文档对象。

在您点击a的情况下,它会触发元素a的点击事件,然后它会传播到li,然后传播到ul单击处理程序注册它被触发,然后它到达bodyhtml和最后到document对象,在那里你注册了其他点击处理程序,这些也会在你停止传播的地方执行但是ul附带的事件已经被解雇了。

li关联的body处理程序未被触发,因为a中的body处理程序阻止了传播

答案 2 :(得分:0)

您正在使用委派的事件侦听器,因此事件处理程序将附加到委派的目标,而不是后代。

前三个事件绑定到body元素,最后一个事件绑定到ul元素,该元素是body的子元素。因此,ul元素上的处理程序将首先触发,因为事件尚未冒泡到body。事件到达body后,传播将停止(如果点击了a标记)。