在阅读本文之前,请在另一页中查看事件列表,API本身非常有帮助,我下面讨论的所有内容都直接链接到此页面。
首先,.click(function)
是 .bind('click', function)
的缩写,它们是等价的。当直接将处理程序绑定到元素时,请使用它们,如下所示:
$(document).click(function() {
alert("You clicked somewhere in the page, it bubbled to document");
});
如果该元素被替换或丢弃,该处理程序将不再存在。此外,当附加处理程序时(例如,选择器找到它时),不存在的元素也不会获得处理程序。
.live()
和
.delegate()
类似相关,
.delegate()
实际上在内部使用
.live()
,它们都监听事件冒泡。这适用于新旧元素,它们以相同的方式冒泡事件。当元素可能会更改时,例如添加新行、列表项等时,您可以使用这些内容。如果没有一个父/共同祖先将留在页面并且在任何时候都不会被替换,请使用
.live()
,如下所示:
$(".clickAlert").live('click', function() {
alert("A click happened");
});
如果您确实有一个父元素没有被替换(因此其事件处理程序不会消失),则应使用.delegate()
来处理它,如下所示:
$("#commonParent").delegate('.clickAlert', 'click', function() {
alert("A click happened, it was captured at #commonParent and this alert ran");
});
这个方法与
.live()
几乎相同,但事件在被捕获并执行处理程序之前冒泡的次数更少。另一个常见用途是当元素的类更改时,不再匹配最初使用的选择器...使用这些方法,选择器在事件发生时进行评估,如果匹配,则运行处理程序...因此,不再匹配选择器的元素无关紧要,它将不再执行。然而,使用
.click()
绑定事件处理程序直接在DOM元素上,它不匹配任何查找它的选择器是无关紧要的...事件被绑定并且会一直保留,直到该元素消失或通过
.unbind()
移除处理程序。
.live()
和
.delegate()
的另一个常见用途是提高性能。如果您正在处理大量元素,则直接向每个元素附加单击处理程序是昂贵且耗时的。在这些情况下,更经济的方法是设置一个单一的处理程序,并让冒泡完成工作,这是一个应用的很好例子,请参阅
take a look at this question where it made a huge difference。
触发事件 - 针对更新的问题
有两个主要的事件处理程序触发函数可用,它们都属于API中相同的“事件处理程序附加”类别, 它们是 .trigger()
和 .triggerHandler()
。.trigger('eventName')
内置了一些常见事件的快捷方式,例如:
$().click(fn); //binds an event handler to the click event
$().click(); //fires all click event handlers for this element, in order bound
您可以在此处查看包括这些快捷方式的列表。
至于区别,.trigger()
触发事件处理程序(但大多数情况下不触发默认操作,例如将光标放置在点击的 <textarea>
中的正确位置)。它会按照绑定的顺序引起事件处理程序(就像本地事件一样),启动本地事件行动,并冒泡到 DOM。
.triggerHandler()
通常用于不同的目的,这里你只是想要激活绑定的处理程序,它不会触发本地事件,例如提交表单。它不会冒泡到 DOM,也不可链式调用(它返回该事件的最后一个绑定事件处理程序返回的任何内容)。例如,如果您想触发一个 focus
事件,但实际上不想聚焦该对象,只需要运行您使用 .focus(fn)
绑定的代码,这将完成此操作,而 .trigger()
将聚焦该元素并冒泡。
这是一个现实世界的例子:
$("form").submit(); //actually calling `.trigger('submit');`
这将运行任何提交处理程序,例如
jQuery验证插件,然后尝试提交
<form>
。但是,如果您只想验证,因为它通过
submit
事件处理程序连接,但之后不提交
<form>
,您可以像这样使用
.triggerHandler('submit')
:
$("form").triggerHandler('submit');
该插件通过在验证检查未通过时终止处理程序来防止提交表单,但使用此方法,我们不关心它的操作。无论它是否中止,我们都不会尝试提交表单,我们只想触发重新验证并且不执行其他操作。(免责声明:由于插件中有一个.validate()方法,因此这是一个多余的示例,但它是意图的一个很好的说明)。
.live()
和.delegate()
的困惑,对一个完全有效的问题表示赞同。 - Nick CraverSO
上发问题。或者这只能通过经验来获得? - xkeshav.trigger()
只是调用事件处理程序...我会在下面的答案中添加描述。 - Nick Craver