据我了解 .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 这样的工具来完成这样的事情。