jQuery中bind方法和live方法有什么区别?

65

我很想知道bind和live函数之间的区别。

对我来说,它们似乎几乎相同。

我阅读了live/bind方法的好处,但它没有告诉我它们之间的区别...

谢谢!


2
除了下面的答案之外,读者可能想看看这篇非常好的文章,它解释了 bindlivedelegate 之间的区别。链接:http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/ - Jon
3
更新:自 jQuery 1.7 版本起,live() 方法已被弃用,推荐使用 on() 方法。 - J.G.Sebring
10个回答

89
简而言之:.bind() 仅适用于您当前在 jQuery 对象中选择的项目。 .live() 将适用于所有当前匹配的元素,以及您将来可能添加的任何元素。
它们之间的根本区别在于 live() 利用了 事件冒泡。也就是说,当您单击按钮时,该按钮可能存在于 <p><div><body> 元素中;因此,实际上,您同时单击了所有这些元素。 live() 的工作原理是将事件处理程序附加到 document 而不是 element。当您像前面所示那样单击该按钮时,文档会接收相同的单击事件。然后,它会向上查找事件目标元素的行,并检查其中是否有任何元素与您的查询匹配。
这样做的结果有两个方面:首先,它意味着您不必继续为新元素重新应用事件,因为它们将在事件发生时隐式添加。但更重要的是(取决于您的情况),它意味着您的代码要轻得多得多!如果页面上有 50 个 <img> 标签,并且您运行此代码:
$('img').click(function() { /* doSomething */ });

...然后该函数会被复制到每个元素中。但是,如果您有以下代码:

$('img').live('click', function() { /* doSomething */ });

如果函数只在文档中的一个位置存储,且在事件发生时应用于与您的查询匹配的所有内容。但由于冒泡行为的存在,并非所有事件都可以以这种方式处理。正如Ichiban所指出的那样,这些受支持的事件是:click、dblclick、mousedown、mouseup、mousemove、mouseover、mouseout、keydown、keypress和keyup。

1
感谢您对如何工作的解释。jQuery文档没有解释任何这方面的内容,这似乎对于使用它很重要。 - harpo
@meagar:“由于这种冒泡行为,不是所有事件都可以通过这种方式处理。正如Ichiban所指出的那样,这些支持的事件包括click、dblclick mousedown、mouseup、mousemove、mouseover、mouseout、keydown、keypress和keyup。”既然在jQuery的后续版本中它适用于所有事件,那么它仍然是附加到body并在body最终接收冒泡事件时触发,还是发生了变化? - mikkelbreum
谢谢,非常棒的答案,易于理解。 - Minh Le
1
编辑:我甚至不确定它会被复制50次;我认为你最终可能会得到50个对单个副本的引用,其中jQuery巧妙地利用apply()和/或call()每次触发事件处理程序时适当地设置this的值。无论如何,这就是我会做的方式。我想检查源代码是唯一确定的方法。 - aroth
我可以为这个问题提供的贡献是:live()方法只能用于选择器,不能用于派生的包装集。 - Joe.wang
显示剩余5条评论

77

.bind()会将事件附加到存在或在调用时匹配选择器的元素上。之后创建的任何元素或因更改类而匹配的元素都不会触发绑定的事件。

.live()适用于现有和未来匹配的元素。在jQuery 1.4之前,仅限于以下事件:click、dblclick、mousedown、mouseup、mousemove、mouseover、mouseout、keydown、keypress、keyup。


34
现在阅读此内容的任何人,.live() 不再局限于上述列出的事件。jQuery 1.4版本中,.live() 事件现在支持所有事件,包括自定义事件。 - Josh Smith
1
这个答案实际上没有回答问题,请查看Nickf的下面答案以获取请求的解释。 - mikkelbreum
Bind只是一个贫乏和有限的生存方式...为什么它还存在呢? - Ben

5

Bind函数将会绑定事件到指定的模式,对于当前DOM中所有匹配的元素在调用时进行绑定。Live函数将会绑定事件到指定的模式,不仅对于当前DOM中的元素生效,也会对于未来添加到DOM中的元素生效。

例如,如果你使用$("div").bind("hover", ...)进行绑定,它将会应用到当前DOM中所有的"div"元素。如果此后你操作DOM并添加了一个额外的"div"元素,它将不会拥有该hover事件的绑定。如果使用live代替bind,则新添加的div元素同样能够接收到该事件。


5

4
假设有这样一种情况:
  1. 我有几个<img>元素。
    • $('img').bind('click', function(){...});
    • 添加一些额外的图像(使用get()html()或其他任何方法)
    • 新的图像没有任何绑定!!
当然,因为在第2步执行$('img')...时,新的图像不存在,所以它没有将事件处理程序绑定到它们身上。
现在,如果你这样做:
  1. 我有几个<img>元素。
    • $('img').live('click', function(){...});
    • 添加一些额外的图像(使用get()html()或其他任何方法)
    • 新的图像确实有绑定!!
这是魔法吗?只是一点点。实际上,jQuery会将一个通用的事件处理程序绑定到DOM树中更高的另一个元素(body?document?不知道),并让事件冒泡。当它到达通用处理程序时,它会检查是否与您的live()事件匹配,如果是,则触发它们,无论元素是在live()调用之前还是之后创建的。

3

除了他们说的之外,我认为最好尽可能地坚持使用 bind,只有在必要时才使用 live


你说得对。.live 对于 AJAX 事件来说是必须的,不是吗? - Kevin Brown
1
为什么这么说?我发现使用 Live 简化了代码。我对性能要求很高,但它看起来对我来说还不错。有什么缺点吗? - Nosredna
首先,并非所有事件都可使用live()。其次,我认为它们更难管理(没有stopPropagation和stopImmediatePropagation)。第三,live()肯定比bind()生成更多的开销(因为它会寻找DOM中的变化)。也许这不是致命的差异,但仍然存在。这就是为什么我倾向于在可能的情况下坚持使用bind()。 - andi
2
live() 不会寻找 DOM 的变化,它维护了一个目标选择器列表,并在事件发生时(事件在 document 上触发)检查它们。这里有一些开销,但非常小。真正的危险是,某些使用 live 的情况可能导致垃圾回收失败。 - eyelidlessness

1
所有这些jQuery方法都用于将事件附加到选择器或元素上。但它们彼此之间都不同。
.bind():这是绑定事件的最简单和快捷的方法。但是,bind()的问题在于它无法为动态添加的与相同选择器匹配的元素工作。bind()只附加事件到当前元素,而不是未来元素。此外,在处理大量选择时,它还存在性能问题。
.live():该方法克服了bind()的缺点。它适用于动态添加的元素或未来元素。由于其在大页面上的性能较差,该方法已被弃用,您应该停止使用它。使用该方法不支持链式编程。
了解更多在这里

0

在我自己愚蠢的调试过程中,我想补充一下。我将.live()应用于页面上的一个按钮类,假设它只会呈现出我尝试通过查询字符串传递的正确ID,并使用ajax调用执行我想要的操作。我的应用程序动态添加了与库存项目相关联的按钮。例如,从顶部向下钻取类别到“COKE”按钮以将可乐添加到您的订单中。再次从顶部向下钻取,然后添加“BUDLITE”-每次我都希望通过AJAX调用将这些项目输入表格。

然而,由于我将.live()绑定到整个按钮类,它会记住我已经进行的每个ajax调用,并为每个后续按钮重新触发它!这有点棘手,因为我并不完全清楚bind和live之间的区别(上面的答案非常明确),所以我想把这个放在这里,以防有人正在搜索这些内容。


0

有一种方法可以获得实时效果,但有点不好。

$(this).unbind('mouseout').bind('mouseout',function(){ });

这将清除之前的内容并重置新内容。在我使用过程中似乎一直很好用。


或者您可以使用适当的事件委托,将事件绑定到“document”,并检查事件的目标。 - eyelidlessness

0

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