jQuery的新on()方法如何与性能中的live()方法进行比较?

时间:2011-12-17 00:55:20

标签: javascript-events event-handling jquery

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
});

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

2 个答案:

答案 0 :(得分:16)

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

你的第一个:

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

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

#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 }); 行为。它在文档上安装一个事件处理程序,并等待针对匹配“#some-button”的对象的点击,以冒泡到文档对象。你的第二个理论上等同于:

live

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

$(document).on('click', '#some-button', function() { //do something when #some-button is clicked }); 被弃用的原因之一是拥有大量.live()处理程序可能是件坏事,因为你在文档对象上获得了很多事件处理程序。然后,每次点击甚至鼠标移动到文档对象的气泡都必须针对很多选择器进行检查,这些选择器可以真正减慢速度。

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

随着.on()的出现(或之前您可以使用.on()执行的操作),您可以更有效地定位“实时”事件处理程序,而不是将它们全部放在文档对象上,而是将它们放在一个不会来去的父对象上,并且更接近真实对象的位置,如下所示:

.delegate()

这会将事件处理程序传播到不同的对象,并使它们更接近实际对象,这意味着您不会最终得到这个巨大的事件处理程序列表,必须在每个鼠标移动时检查选择器或点击事件。这就是$('#some-button-parent').on('click', '#some-button', function() { //do something when #some-button is clicked /////// }); 被替换和弃用的原因。最好使用.live().delegate()并指定一个不如文档对象那么远的父对象。

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

所以,这就是关于它们如何工作以及为什么一个配置应该优于另一个配置的理论。如果要测试实际性能,则必须在事件处理程序传播和分发方面进行某种性能测试,可能是在有大量“实时”事件处理程序的情况下。该测试可能并不容易,因为在事件处理程序的开始/结束时可能很难获得时序信息。你不能轻易地使用像jsperf这样的工具来做这样的事情。

答案 1 :(得分: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以外的其他内容。< / p>

这在jQuery文档中都有解释:

  

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

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