6

我已经阅读了 jQuery 文档,并且我知道如果我使用 live() 将事件绑定到元素,那么使用 stopPropagation() 是没有意义的,因为带有 live() 的事件绑定到文档节点,所以事件已经开始了。这么说,我认为 nex 代码会发出 3 次警报,因为 stopPropagation 不会停止任何事情:

<ul style="border:red solid 1px;">
    <li style="padding:10px; border:blue solid 1px;">
        <p style="border:green solid 1px;"><a href="#">link</a></p>
    </li>
    <li style="padding:10px; border:blue solid 1px;">
        <p style="border:green solid 1px;">no link</p>
    </li>
</ul>

<script type="text/javascript">
    $('a').live( "click", function( e ) {alert("link");e.stopPropagation()} );
    $('ul').live( "click", function( e ) {alert("ul");} );
    $('ul li').live( "click", function( e ) {alert("li");} );
</script>

当我单击链接时,我期望并警告“li”和“ul”,但是 stopPropagation 正在停止其他应该无用的事件。我错过了什么?

4

1 回答 1

6

根据文档 stopPropagation()不能live()按预期工作,因为live()仅在事件已经冒泡到document.

但是,如果您使用 jQuery 1.4.3 或更高版本stopPropagation()开始工作。

live()自 1.4.3 以来被多次重写。
live()文档列出了许多首选使用其他绑定方法的原因。尽管文档中的信息似乎是指 1.4.1 的行为,并且似乎与当前的实际行为没有 100% 同步。

例如,查看添加的 1.7.1 Sourceon()显示live()正在使用on()

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

演示- 使用您的代码并使用 jQuery 1.4.1 - stopPropagation 无法正常工作,正如预期的那样

演示- 使用您的代码并使用 jQuery 1.4.3 - stopPropagation 现在正在工作

概括

live()在 1.4.3 中重写。我假设由于delegate()当时已添加。
live()随着改进的增加,每个版本的 jQuery 都在不断更新。

一般来说,为了防止任何令人惊讶的结果,live()最好遵循文档中的指南,并为给定版本的 jQuery 使用建议的方法:

$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+

为了完整起见,我在live()下面添加了 1.4.1 和 1.4.3 的源代码提取。

1.4.1 来源

live: {
    add: function(proxy, data, namespaces, live) {
        jQuery.extend(proxy, data || {});

        proxy.guid += data.selector + data.live;
        data.liveProxy = proxy;

        jQuery.event.add(this, data.live, liveHandler, data);

    },

    remove: function(namespaces) {
        if (namespaces.length) {
            var remove = 0,
                name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");

            jQuery.each((jQuery.data(this, "events").live || {}), function() {
                if (name.test(this.type)) {
                    remove++;
                }
            });

            if (remove < 1) {
                jQuery.event.remove(this, namespaces[0], liveHandler);
            }
        }
    },
    special: {}
}

1.4.3 来源

live: {
    add: function(handleObj) {
        jQuery.event.add(this, liveConvert(handleObj.origType, handleObj.selector), jQuery.extend({}, handleObj, {
            handler: liveHandler,
            guid: handleObj.handler.guid
        }));
    },

    remove: function(handleObj) {
        jQuery.event.remove(this, liveConvert(handleObj.origType, handleObj.selector), handleObj);
    }
}
于 2012-12-19T09:57:55.940 回答