jQuery live方法有什么问题?

30

live() 方法已经被 jQuery 1.7 废弃。现在,jQuery 文档推荐使用:

使用 .on() 来绑定事件处理程序。在旧版的 jQuery 中,用户应该使用 .delegate() 而不是 .live()

我知道如何使用 ondelegate,但我不了解它们为什么更好。相比之下,live() 方法更简单易用。

为什么要废弃 live 方法?其他方法有哪些优点?如果我继续使用 live 方法,会出现什么问题吗?


1
除了当他们停止支持它时你的代码会出问题之外,没什么了...特别是如果你使用本地副本的jQuery... - Lix
4
以下的回答很好,但是关于deprecation还有一个实际方面:工具包的开发人员不再需要支持“live”。因为他们已经添加了“on”并认为它是一个好的解决方案,所以他们不再想支持和维护“live”,所以无论它是好是坏,都已经被标记为过时。在这种情况下,有一些原因可以避免使用“live”,但通常情况下,如果工具包添加了一个方法,开发人员可能会选择将执行类似操作的方法标记为过时以便于维护。 - Dancrumb
7个回答

33

参考以下解释:

http://www.ultimatewebtips.com/why-jquery-live-is-a-bad-option-to-use/(该网站似乎已关闭)

引用:

  1. 无法将.live()用于可重用的小部件。

  2. .stopPropagation()无法与.live()一起使用。

  3. .live()更慢。

  4. .live()不能链式调用。

此外,.on()的优美之处在于可以很好地流畅处理所有事件:http://api.jquery.com/on/

你知道API链接并查看.on()如何工作:)

引用:

  

.on()方法将事件处理程序附加到jQuery对象中当前选择的元素集。从jQuery 1.7开始,.on()方法提供了附加事件处理程序所需的所有功能。有关从较旧的jQuery事件方法进行转换的帮助,请参见 .bind(),.delegate()和.live()。要删除使用.on()绑定的事件,请参见.off()。要附加仅运行一次然后删除自身的事件,请参见.one()


1
尽管在jQuery 1.9中删除了.live(),但是需要对第1、2和3点进行严格的限定,而第4点则完全错误。 - Beetroot-Beetroot

10

live()有两个低效的原因:

  • 在构造函数$('selector').live()中,jQuery首先需要选择所有元素。然而,调用live()时,它只需要jQuery对象中的选择器(存储在.selector中),而不实际使用任何选定的元素。因此,首先选择所有匹配元素,然后不使用它们有点浪费。 on()delegate()将目标选择器作为参数,这意味着没有目标元素被预先选择,并且测试仅在事件触发时发生。
  • live()默认绑定到document级别,因此所有事件都需要冒泡通过整个DOM。您可以通过使用$(selector, context).live()指定上下文来缩小范围,但最好使用on()delegate()来做到这一点。

编写新代码时,强烈建议使用最新和最好的on()而不是delegate()和已弃用的live()。但是,我认为支持live()不会很快(如果有的话)被取消,因为有很多脚本依赖它。此外,使用live()而不是on()没有实际缺点,因为在jQuery源代码中,live()被定义为:

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

$(selector, context)дёҚдјҡж”№еҸҳ.contextпјҢеӣ жӯӨе®ғд»Қ然жҳҜdocumentгҖӮжӮЁеҝ…йЎ»дј йҖ’DOMе…ғзҙ пјҢдҫӢеҰӮ$($("body")[0]).find("span")пјҢд»Ҙе°Ҷ.contextжӣҙж”№дёәе…¶д»–еҶ…е®№гҖӮ - Esailija

4

live方法存在两个主要问题:

  1. 它在文档级别上附加所有事件处理程序,因此任何冒泡到文档的事件都必须与所有现有的live事件的事件类型和选择器进行匹配。如果你有很多事件,页面会变得缓慢。你应该使用delegateon来限制检查事件的范围。

  2. 该方法的用法与库中其他方法使用选择器的方式不太一致。你只能在使用选择器创建jQuery对象时使用它。而delegateon方法则更为自然,因为你可以向方法提供选择器。


1

我相当确定这是由于.live()的本质导致的。它很方便,但使用它是一个不好的习惯,因为它强制你的浏览器在大多数情况下搜索更多的事件。

与其默认搜索整个文档的某个事件,更节省数据的做法是搜索特定的容器。

live()确实很方便使用,我们大多数人从未注意到使用它存在任何缺陷。在我的眼中,它基本上是一个改进版的bind()

但在许多情况下,我们必须适应并更清晰地告诉我们的代码需要执行什么。

这就像问自己为什么要导入东西,而不是在初始化时将所有东西都导入。


我认为你可以通过选择字符串来限制搜索范围,例如 "#mydiv .edit" 而不是 ".edit" - Peter Olson
不完全是。live() 在每次事件执行时都会检查整个文档中是否存在 #mydiv 内部的 .edit。而不是查找现有的 #mydiv 并检查其子元素。 - Robin Castlin

1

live()将处理程序附加到文档,这基本上会拦截给定类型的所有事件,从而产生查找与选择器匹配的元素的成本。使用delegate()on()时,建议更靠近预期的目标(如果可能,在它们的直接父级中),从而缩小处理的事件数量,并相应地搜索匹配的目标。


1

这里有一篇由Paul Irish撰写的关于live()性能和限制的详细文章article by Paul Irish

如果您继续使用live,在项目中升级jQuery库后,您的代码可能会出现问题。


0

$('some selector').live(' ... ', handler)

$(document).on(' ... ', 'some selector', handler)

是一样的。

所以当你使用live时,实际上是将所有处理程序分配给DOM树的根。这有两个缺点:

  1. 将处理程序附加到DOM根会增加事件冒泡时所需遍历的路径。这会对性能产生不良影响。
  2. 存在更高的风险,即某些其他处理程序在末尾使用return false将阻止live处理程序触发。

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