Events stopPropagation和live()方法。我错过了什么?

Events stopPropagation和live()方法。我错过了什么?,events,jquery,stoppropagation,Events,Jquery,Stoppropagation,我读过jQuery文档,我知道如果我使用live()将事件绑定到元素,那么使用stopPropagation()是没有意义的,因为带有live()的事件绑定到文档节点,因此事件已经发生了。话虽如此,我认为nex代码会发出3次警报,因为StopRopagation不会停止任何操作: <ul style="border:red solid 1px;"> <li style="padding:10px; border:blue solid 1px;">

我读过jQuery文档,我知道如果我使用live()将事件绑定到元素,那么使用stopPropagation()是没有意义的,因为带有live()的事件绑定到文档节点,因此事件已经发生了。话虽如此,我认为nex代码会发出3次警报,因为StopRopagation不会停止任何操作:

<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>
    填充:10px;边框:蓝色实心1px;“>

    填充:10px;边框:蓝色实心1px;“> 无链接

$('a').live(“click”,函数(e){alert(“link”);e.stopPropagation()}); $('ul').live(“click”),函数(e){alert(“ul”);}; $('ul li').live(“点击”,函数(e){alert(“li”);});
当我点击链接时,我期待并警告“li”和“ul”,然而StopRopagation正在停止其他本应无用的事件。 我遗漏了什么?

根据
stopPropagation()
live()
中不起作用,因为
live()
仅在事件已冒泡到
文档后执行该事件

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

live()
自1.4.3以来多次被重写。
live()
文档列出了许多为什么首选使用其他绑定方法的原因。文件中的信息似乎涉及1.4.1行为,似乎与当前的实际行为不完全同步

例如,查看添加了
on()
的1.7.1源代码,它显示
live()
正在使用
on()

-使用您的代码并生活在jQuery 1.4.1中-StopRopagation未按预期工作

-使用您的代码并在jQuery 1.4.3中生活-StopRopagation现在正在工作

总结
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+

为了完整性,我在下面添加了1.4.1和1.4.3的
live()
源代码摘录

1.4.1来源
为什么不干脆
$('a')。在(“单击”,函数(){alert(“link”);返回false;})?如果我单击确切的链接,您的代码将按预期工作。我没有看到ul和li警报。如果单击实际链接旁边的空间,我会看到其他两个警报。您可能希望设置元素的宽度,以便不会看到此行为。这似乎是因为对于ul和ul li,您还使用了
live
。如果你把它们改成
bind
,它们都会被调用。不管怎样,我投了反对票,因为你90%的帖子被误导了,
live
与delegation@Esailija:我在1.4.1中添加了演示,展示了它的工作原理,并在1.4.3中添加了关于更改的注释。在1.4.3中,重新编写了
live()
,很可能是因为当时添加了
delegate()
<代码>live()
是在1.4.1中添加的,其中
StopRoPagation()
未按预期工作。在1.4.3中,添加了超级种子
live()
。我想这就是为什么jQuery
live()
在每次发布时都会被重新编写的原因,如果有改进的话。为了方便起见,我还添加了live in 1.4.1和1.4.3的源代码。这种行为仍然很奇怪和不直观,它们都绑定到
文档
,并且只在
文档
上处理,只有
e.stopImmediatePropagation
应该有效。例如,这应该是等效的,但事实并非如此@伊莎莉亚:我完全同意。真奇怪。我在
live()
的文档中也找不到任何关于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: {
    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: {}
}
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);
    }
}