【问题标题】:How does jQuery's new on() method compare to the live() method in performance?jQuery 的新 on() 方法在性能上与 live() 方法相比如何?
【发布时间】:2011-12-17 09:36:55
【问题描述】:

jQuery 有一个名为on() 的新方法,建议替换delegate()live().bind()

例如,同时使用这两种方法:

$('#some-button').on('click', function() {
    //do something when #some-button is clicked
});
$('#some-button').live('click', function() {
    //do something when #some-button is clicked
});

哪个表现更好? (我确实知道这两个事件上下文都在文档级别。)

【问题讨论】:

  • 最好的方法是计时。
  • 第一个执行得更好,因为您将处理程序直接绑定到元素(而不是文档根)。你在比较苹果和橘子。将处理程序绑定到目标元素越近,它就会越早执行。这是否会影响您的应用程序的性能取决于它本身以及您正在使用的 DOM 树。
  • 同样重要的是 ".live()" 有点愚蠢,因为 jQuery 必须在原始调用中实际为选择器构建元素列表,但该元素列表本质上是忽略。 “.live()”API 基本上是一个糟糕的设计,自从引入“.delegate()”以来,就没有理由使用它了。
  • JSPerf 是一种无需创建自己的循环即可为代码执行计时的简便方法。这是我为回答您的问题而制作的示例:jsperf.com/jquery-live-vs-on

标签: javascript-events event-handling jquery


【解决方案1】:

据我了解 .live().on(),您所包含的两个示例并不是一回事。

你的第一个:

$('#some-button').on('click', function() {
    //do something when #some-button is clicked
});

没有live 行为。它找到#some-button 对象并直接在其上安装一个事件处理程序。这是非常有效的,但没有.live() 行为。如果此时#some-button 对象不存在,则不会安装任何事件处理程序。和这个基本一样:

$('#some-button').click(function() {
    //do something when #some-button is clicked
});

你的第二个:

$('#some-button').live('click', function() {
    //do something when #some-button is clicked
});

具有live 行为。它在文档上安装一个事件处理程序,并等待针对与“#some-button”匹配的对象的点击冒泡到文档对象。你的第二个理论上相当于这个:

$(document).on('click', '#some-button', function() {
    //do something when #some-button is clicked
});

我说理论上是等效的,因为它应该安装相同的事件处理程序,但我不知道处理两者的jQuery代码是否相同。

.live() 已被弃用的原因之一是拥有大量 .live() 处理程序可能是一件坏事,因为您会在文档对象上获得大量事件处理程序。然后,每次点击甚至鼠标移动都会冒泡到文档对象,必须对照大量选择器进行检查,这确实会减慢速度。

.live() 的另一个问题是它会在您拨打电话时评估选择器“#some-button”,但实际上并未使用该结果,因此很浪费。 .on() 版本不会在您进行第一次调用时评估作为参数传递给 .on() 的选择器,因为当时不需要它 - 只有在需要比较实际点击时才需要它到选择器。

随着.on() 的出现(或者您以前可以用.delegate() 做的事情),您可以更有效地定位您的“实时”事件处理程序,方法是不将它们全部放在文档对象上,而是将它们放在一个不来来去去的父对象,并且更接近真实对象的位置,例如:

$('#some-button-parent').on('click', '#some-button', function() {
    //do something when #some-button is clicked ///////
});

这会将事件处理程序分散到不同的对象,并使它们更接近它们所指的实际对象,这意味着您最终不会得到这个巨大的事件处理程序列表,每次鼠标移动或点击事件。这就是.live() 已被替换和弃用的原因。最好使用.delegate().on() 并指定一个与文档对象相距不远的父对象。

新的.on() 语法的优势在于,您现在可以使用相同的方法同时处理“实时”和“静态”事件处理程序,只需改变传递参数的方式即可。 jQuery 对象是安装事件处理程序的位置,第二个参数中的可选选择器是事件目标必须匹配的选择器。如果您传递该选择器,则所有命中 jQuery 对象中指定的对象的事件都将根据该选择器检查其目标。如果没有选择器,则只匹配target与jQuery对象中指定的对象相同的对象。

所以,这就是关于它们如何工作以及为什么一种配置应该比另一种更好的所有理论。如果您想测试真实世界的性能,您可能必须在有很多“实时”事件处理程序的场景中设计某种关于事件处理程序传播和分发的性能测试。该测试可能并不容易进行,因为可能很难在事件处理程序的开始/结束时获取时间信息。你不能轻易地使用像 jsperf 这样的工具来完成这样的事情。

【讨论】:

    【解决方案2】:

    这是一个性能测试,您可以在自己的浏览器中运行,看看哪个更快:http://jsperf.com/jquery-live-vs-on

    .on().live() 一起使用的示例在功能上并不相同,这里列出了.on().delegate().live() 的工作原理:

    $(<selector>).on(<event>, <handler>) 在功能上与:$(<selector>).bind(<event>, <handler>) 相同。

    $(<root-element>).on(<event>, <selector>, <handler>) 在功能上与:$(<root-element>).delegate(<selector>, <event>, <handler>) 相同。

    $(<selector>).live(<event>, <handler>) 在功能上与 $(document).delegate(<selector>, <event>, <handler>) 相同,在功能上与:$(document).on(<event>, <selector>, <handler>) 相同。

    如您所见,.live().delegate() 基本相同,但.delegate() 提供将<root element> 更改为document 以外的其他内容的功能。

    这在 jQuery 文档中都有解释:

    从 jQuery 1.7 开始,不推荐使用 .live() 方法。使用 .on() 来 附加事件处理程序。旧版本 jQuery 的用户应该使用 .delegate() 优先于 .live()。

    来源:http://api.jquery.com/live

    【讨论】:

    • +1。谢谢,我不知道jsperf。以及不错的功能比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 2021-02-07
    相关资源
    最近更新 更多