jQuery .live() 和 .on() 有什么区别?

85

我看到jQuery1.7中有一个新方法.on(),它取代了早期版本中的.live()

我很想知道它们之间的差异以及使用这种新方法的好处是什么。

8个回答

99

文档中很清楚地说明了为什么您不应该使用live方法。正如Felix所提到的,.on是一种更加流畅的附加事件的方式。

不再推荐使用.live()方法,因为jQuery的后续版本提供了更好的方法,这些方法没有它的缺点,特别是在以下情况下使用.live()会出现以下问题:

  • 在调用.live()方法之前,jQuery尝试检索由选择器指定的元素,在大型文档上可能会耗费时间。
  • 不支持链式调用方法。例如,“$("a").find(".offsite, .external").live( ... );”不是有效的,也不会按预期工作。
  • 由于所有.live()事件都附加到document元素,因此事件在处理之前需要经过最长和最慢的路径。
  • 在事件处理程序中调用event.stopPropagation()无法阻止文档较低位置附加的事件处理程序;事件已经传播到document。
  • .live()方法以出人意料的方式与其他事件方法交互,例如,$(document).unbind("click")将删除通过任何对.live()的调用附加的所有单击处理程序!

8
想知道,如果这是关键所在,为什么不改进现有的直播方法,而要创建一个新的方法?除非存在一些直播无法做到但新方法可以做到的事情? - neobie
1
@neobie,这是为了让你的代码更有意义,更具统一性。 - Om Shankar
@neobie: 我想这是为了保持向后兼容性。此答案中指出的差异显示它们的行为略有不同。如果修改 live() 的行为与 on() 相同,可能会破坏现有的代码。jQuery 团队已经表明他们并不一定害怕“破坏”遗留代码,但我想在这种情况下,他们决定不冒险引入回归。 - rinogo
看起来是这样。live()在1.7中被弃用并在1.9中被移除。http://api.jquery.com/live/ - rinogo

12

当人们从.live()转换到.on()时,可能会遇到一个差异,即使用.on()为动态添加到DOM的元素绑定事件时,参数略有不同。

以下是我们曾经使用.live()方法的语法示例:

$('button').live('click', doSomething);

function doSomething() {
    // do something
}

现在使用 jQuery 版本 1.7 中已弃用的 .live() 方法并在版本 1.9 中已删除,你应该使用 .on() 方法。以下是使用 .on() 方法的等效示例:

$(document).on('click', 'button', doSomething);

function doSomething() {
    // do something
}
请注意,我们是针对文档而不是按钮本身调用.on()。我们在第二个参数中指定要监听事件的元素的选择器。
在上面的示例中,我正在对文档调用.on(),但是如果您使用与选择器更接近的元素,则可以获得更好的性能。任何祖先元素都可以使用,只要它在调用.on()之前存在于页面上。
这在文档中解释,但很容易被忽视。

4

查看官方博客

[...] 新的 .on() 和 .off() API 统一了 jQuery 中所有将事件附加到文档的方式 - 而且它们键入更短! [...]


2
.live()

该方法用于为所有匹配当前选择器的元素附加事件处理程序,现在和将来都有效。

$( "#someid" ).live( "click", function() {
  console.log("live event.");
});

而且。
.on()

这个方法用于将一个或多个事件的事件处理函数附加到选定的元素上,以下是示例。

$( "#someid" ).on( "click", function() {
  console.log("on event.");
});

1

关于on和live的区别的好教程

来自上述链接的引用

.live() 方法有什么问题?
由于 jQuery 的后续版本提供了更好的方法,不再推荐使用 .live() 方法。特别是以下问题会出现在使用 .live() 时:
  1. jQuery 在调用 .live() 方法之前尝试检索选择器指定的元素,在大型文档上可能耗时较长。
  2. 不支持链接方法。例如,$(“a”).find(“.offsite, .external”).live( … ); 不是有效的,并且不能按预期工作。
  3. 由于所有 .live() 事件都附加到文档元素,因此事件在处理之前需要经过最长和最慢的路径。
  4. 在事件处理程序中调用 event.stopPropagation() 无法阻止已附加到文档较低位置的事件处理程序;事件已经传播到文档。
  5. .live() 方法以意想不到的方式与其他事件方法交互,例如,$(document).unbind(“click”) 将删除任何对 .live() 的调用附加的所有单击处理程序!

0

了解更多信息,请查看 .live().on()

.live() 方法用于处理动态生成内容的情况...就像我创建的一个程序,当我改变Jquery滑块的值时,它会添加一个选项卡,并且我想将关闭按钮功能附加到每个生成的选项卡上...我尝试过的代码是..

var tabs = $('#tabs').tabs();
                                        // live() methos attaches an event handler for all
                                        //elements which matches the curren selector
        $( "#tabs span.ui-icon-close" ).live( "click", function() {


            // fetches the panelId attribute aria-control which is like tab1 or vice versa
            var panelId = $( this  ).closest( "li" ).remove().attr( "aria-controls" );
            $( "#" + panelId ).remove();
            tabs.tabs( "refresh" );
        });

它运行得相当不错...


欢迎来到SO。请尽量详细阐述您的答案,不要仅提供链接,因为在这里,仅有链接的答案被认为是不好的做法。 - mata
谢谢,我会记住这个,以备将来回答的时候用。 :) - Hiren

0

我是Chrome扩展"Comment Save"的作者,它使用了jQuery,其中一个使用了.live()。该扩展的工作方式是通过使用.live()将监听器附加到所有文本区域上-这很有效,因为每当文档更改时,它仍会将监听器附加到所有新的文本区域。

我转向了.on(),但它效果不佳。它不会在文档更改时附加监听器-所以我已经回到使用.live()。我想这可能是.on()中的一个错误。只是要小心一点吧。


10
你可能使用方法不正确 - 它的语法与.live()方法略有不同。对于$('p').live('click', function () { alert('clicked'); });等价的.on()方法是$(document).on('click', 'p', function () { alert('clicked'); });。注意,在第一个参数中使用.on()方法来操作document,然后在第二个参数中指定要监听事件处理程序的元素。 - ajbeaven
1
你可以在这里阅读更多内容:http://api.jquery.com/on/。查看“直接和委托事件”标题下的内容。 - ajbeaven
1
我建议你也阅读一下这篇文章:http://www.elijahmanor.com/2012/02/differences-between-jquery-bind-vs-live.html - ajbeaven
1
我们还可以使用 $(selector1).on(event,selector2,function) 的方式,其中 selector1 是父级选择器,selector2 是 selector1 的子级选择器。这样可以最小化搜索区域,因为您不必搜索整个文档。 - Ramsharan
1
@ajbeaven,你应该把你在这里的第一条评论变成一个答案(这就是我来到这里寻找的东西)。 - atwright147
显示剩余4条评论

-1

我有一个需求,需要识别浏览器关闭事件。经过一番研究,我使用jQuery 1.8.3进行了以下操作:

  1. 当单击超链接时,使用以下jQuery打开标志

    $('a').live('click', function() {cleanSession = false;});

  2. 当任何时间输入按钮类型的提交被点击时,使用以下jQuery打开标志

$("input[type=submit]").live('click',function(){alert('input button clicked');cleanSession=false;});

  1. 当任何时间表单提交发生时,使用以下jQuery打开标志

$('form').live('submit', function() {cleanSession = false;});

现在重要的事情是...我的解决方案只适用于使用.live而不是.on。如果我使用.on,那么事件会在表单提交后触发,这太晚了。很多时候,我的表单使用javascript调用(document.form.submit)来提交。

因此,.live和.on之间存在关键差异。如果您使用.live,您的事件将立即触发,但如果您切换到.on,则不会及时触发。


1
这不是真的,你一定是在错误地使用.on方法或者你代码中的其他部分导致了这种情况。也许你可以把你使用.on方法的代码粘贴出来。 - ajbeaven
是的,这不是真的。.on() 是 .live() 的改进版本。因此,请在此处粘贴您的代码。这样我们就会有一些清晰度。 - RecklessSergio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接