jQuery .live()vs .on()方法,用于在加载动态html后添加click事件

Sea*_*man 209 javascript jquery events dom handler

我正在使用jQuery v.1.7.1,其中.live()方法显然已被弃用.

我遇到的问题是,当使用以下方法动态将html加载到元素中时:

$('#parent').load("http://..."); 
Run Code Online (Sandbox Code Playgroud)

如果我之后尝试添加click事件,则不会使用以下任一方法注册事件:

$('#parent').click(function() ...); 
Run Code Online (Sandbox Code Playgroud)

要么

// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...); 
Run Code Online (Sandbox Code Playgroud)

实现此功能的正确方法是什么?它似乎只适用于.live(),但我不应该使用该方法.请注意,#child是动态加载的元素.

谢谢.

jfr*_*d00 594

如果您希望click处理程序适用于动态加载的元素,那么您可以在父对象上设置事件处理程序(不会动态加载)并为其提供一个与您的动态对象匹配的选择器,如下所示:

$('#parent').on("click", "#child", function() {});
Run Code Online (Sandbox Code Playgroud)

事件处理程序将附加到#parent对象,并且只要点击事件冒泡到它起源#child,它就会触发您的点击处理程序.这称为委托事件处理(事件处理委托给父对象).

它是以这种方式完成的,因为你可以将事件附加到#parent对象,即使#child对象尚不存在,但是当它稍后存在并被点击时,click事件将冒泡到#parent对象,它将看到它起源于#child和有一个事件处理程序,用于单击#child并触发您的事件.

  • **很棒**解释!我以前从来没有能够围绕`live()`与`on()`进行包围,但今晚我又决定再试一次,你的解释立即揭示了我一直以来所遗忘的东西.谢谢! (21认同)
  • 你应该考虑写一本书或者其他东西:你的小文本比jQuery文档中关于«_on()_»的整页更有帮助.**非常感谢!** (7认同)
  • **一百万**.我开始使用淘汰赛之前我意识到这可以在jQuery中为动态创建的孩子,非常感谢你. (4认同)

Boj*_*les 32

试试这个:

$('#parent').on('click', '#child', function() {
    // Code
});
Run Code Online (Sandbox Code Playgroud)

$.on()文档:

事件处理程序仅绑定到当前选定的元素; 它们必须存在于您的代码调用时页面上.on().

#child当您调用$.on()它时,您的元素不存在,因此事件不受约束(不像$.live()).#parent但是,确实存在,所以将事件绑定到那就好了.

以上在我的代码的第二个参数作为一个"过滤器",以仅触发事件是否鼓泡到#parent#child.

  • @SeanThoman - 你必须从`.load()`方法的成功处理程序调用它 - 而不是从`.load()`方法之后的代码调用它.只有成功处理程序实际执行时才会加载`#child`,而不是之前. (6认同)

L42*_*22Y 21

$(document).on('click', '.selector', function() { /* do stuff */ });

编辑:我提供了更多关于它如何工作的信息,因为...单词.在此示例中,您将在整个文档上放置一个侦听器.

当你click在任何匹配的元素上时.selector,事件会冒泡到主文档 - 只要没有其他侦听器调用event.stopPropagation()方法 - 这会将事件冒泡到父元素之上.

您正在侦听来自与指定选择器匹配的元素的任何事件,而不是绑定到特定元素或元素集.这意味着您可以一次创建一个侦听器,该侦听器将自动匹配当前现有元素以及任何动态添加的元素.

这很聪明,原因有几个,包括性能和内存利用率(在大型应用程序中)

  • 他试过`$(element).on(...)`.这是`$(document).on(...,element,...)`.不同的野兽. (23认同)

Jar*_*red 12

1.7中的.live()相当于:

$(document).on('click', '#child', function() ...); 
Run Code Online (Sandbox Code Playgroud)

基本上,观察单击事件的文档并为#child过滤它们.

  • 现在弃用`.live()`的一个原因是因为将所有实时事件处理程序放在文档对象上是不好的.事情真的可以放慢速度.事件不仅必须一直冒泡到文档,而且可能有很多事件处理程序可以查看文档对象.`.on()`的主要优点是可以将它附加到更接近实际对象的父对象,并大大提高性能.所以...我不建议在文档对象中使用`.on()`.选择更近的父对象要好得多. (17认同)

NSV*_*NSV 9

我知道答案有点晚了,但我已经为.live()方法创建了一个polyfill.我在jQuery 1.11中测试过它,它看起来效果很好.我知道我们应该尽可能地实现.on()方法,但是在大型项目中,无论出于何种原因,都无法将所有.live()调用转换为等效的.on()调用,以下可能工作:

if(jQuery && !jQuery.fn.live) {
    jQuery.fn.live = function(evt, func) {
        $('body').on(evt, this.selector, func);
    }
}
Run Code Online (Sandbox Code Playgroud)

只需在加载jQuery之后和调用live()之前包含它.


Mat*_*att 5

.on()适用于jQuery 1.7及以上版本.如果您使用的是旧版本,请使用以下命令:

$("#SomeId").live("click",function(){
    //do stuff;
});
Run Code Online (Sandbox Code Playgroud)

  • OP说"我正在使用jQuery v.1.7.1" (8认同)
  • @MatthewPatrickCashatt - 我确实发表了自己的答案,并没有给你的回答 - 不要做出如此盲目的假设.Pre 1.7,`.delegate()`比`.live()`执行得更好,这就是jQuery doc推荐它并弃用`.live()`的原因.是的,`.live()`仍然有效,但是这里的答案应该推荐更好的做事方式.我在这里已经看过20次了.如果你在SO上发布带有`.live()`的代码,那么它会被投票(除非我有其他严重的错误,否则通常不会被我用). (5认同)