jQuery`click`,`bind`,`live`,`delegate`,`trigger`和`on`函数之间的差异(举例)?

我已经阅读了jQuery official website上的每个函数的文档,但是下面的函数之间没有这样的比较列表:

 $().click(fn) $().bind('click',fn) $().live('click',fn) $().delegate(selector, 'click', fn) $().trigger('click') // UPDATED $().on('click', selector ,fn); // more UPDATED 

请避免任何参考链接。

上述所有function如何正确工作,在哪种情况下应该首选?

注意:如果有其他函数具有相同的function或机制,请详细说明。

更新

我也看到了$.trigger函数。 它是否与上述function类似?

更新

现在.on被添加到.on中,我认为这个包含了所有上述function要求。

在阅读之前, 把这个事件列表放在另一个页面上,API本身是非常有用的,下面我正在讨论的所有内容都直接从这个页面链接 。

首先, .click(function)实际上是.bind('click', function)一个快捷方式,它们是等价的。 直接将处理程序绑定到元素时使用它们,如下所示:

 $(document).click(function() { alert("You clicked somewhere in the page, it bubbled to document"); }); 

如果这个元素被replace或扔掉,这个处理程序将不再存在。 当这个代码运行来附加处理程序(例如,select器发现它) ,不在那里的元素将不会得到处理程序。

.live().delegate()类似地相关, .delegate()实际上在内部使用.live() ,它们都监听事件的冒泡。 这适用于新旧元素 ,它们以同样的方式冒泡事件。 当元素可能发生变化时,可以使用这些元素,例如添加新行,列表项等。如果没有父类/公共祖先将保留在页面中,并且在任何时候都不被replace,请使用.live() ,喜欢这个:

 $(".clickAlert").live('click', function() { alert("A click happened"); }); 

如果你有一个父元素没有被replace(所以它的事件处理程序不会被再见),你应该使用.delegate()来处理它,如下所示:

 $("#commonParent").delegate('.clickAlert', 'click', function() { alert("A click happened, it was captured at #commonParent and this alert ran"); }); 

这和.live()几乎是一样的,但事件在被捕获和处理程序执行之前会冒泡次数less。 这两个的另一个常见用法是说你的类改变了一个元素,不再匹配你最初使用的select器…在这些方法中,select器在事件发生时被评估,如果匹配,处理程序运行..因此不再与select器相匹配的元素将不再执行。 然而,使用.click() ,事件处理程序绑定在DOM元素上,事实上它不匹配任何用来find它的select器是不相关的…事件是绑定的,直到元素消失,或者处理程序通过.unbind()被移除。

.live().delegate()另一个常见用途是性能 。 如果处理大量元素,则直接将点击处理程序附加到每个元素上既昂贵又耗时。 在这种情况下,设置一个处理程序并让冒泡工作更为经济, 在这个问题上做出了巨大的改变 ,这是应用程序的一个很好的例子。


触发 – 为更新的问题

有2个主要的事件处理程序触发函数可用, 它们属于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');` 

这将运行任何提交处理程序,例如jQueryvalidation插件 ,然后尝试提交<form> 。 然而,如果你只是想validation,因为它通过submit事件处理程序挂钩,但不提交<form>之后,你可以使用.triggerHandler('submit') ,如下所示:

 $("form").triggerHandler('submit'); 

如果validation检查没有通过,插件会阻止处理程序通过轰炸提交表单,但是使用这种方法,我们不关心它的作用。 无论是否中止,我们不是试图提交表格,我们只是想触发它重新validation,什么也不做。 ( 免责声明:这是一个多余的例子,因为在插件中有一个.validate()方法,但它是一个体面的插图意图)

前两个是相同的。

 // The following two statements do the same thing: $("blah").click( function() { alert( "Click!" ); } ); $("blah").bind( "click", function() { alert( "Click!" ); } ); 

然而,第二个可以同时绑定多个事件,方法是指定几个空格分隔的事件名称:

 $("blah").bind( "click mouseover mouseout", function() { alert( "Click! Or maybe mouse moved." ); } ); 

.live方法更有趣。 考虑下面的例子:

 <a class="myLink">A link!</a> <a id="another">Another link!</a> <script> $("a.myLink").click( function() { alert( 'Click!' ); } ); $("a#another").addClass( "myLink" ); </script> 

脚本的第二行执行后,第二个链接也会有一个“myLink”的CSS类。 但它不会有事件处理程序,因为事件被附加时它没有类。

现在考虑你希望它是相反的方式:每当类“myLink”的链接出现在页面的某个地方,你希望它自动具有相同的事件处理程序。 当你有某种列表或表格时,这是非常常见的,你可以dynamic地添加行或单元格,但是希望它们都以相同的方式运行。 而不是每次重新分配事件处理程序的所有痛苦,您可以使用.live方法:

 <a class="myLink">A link!</a> <a id="another">Another link!</a> <script> $("a.myLink").live( "click", function() { alert( 'Click!' ); } ); $("a#another").addClass( "myLink" ); </script> 

在这个例子中,第二个链接一旦获得“myLink”类,也将获得事件处理程序。 魔法! 🙂

当然,这不是字面的。 .live实际上做的是不把处理程序附加到指定的元素本身,而是附加到HTML树的根(“body”元素)。 DHTML中的事件有这个“冒泡”的有趣特征。 考虑这个:

 <div> <a> <b>text</b> </a> </div> 

如果你点击“文本”,那么首先<b>元素会得到一个“点击”事件。 之后,<a>元素将获得一个“点击”事件。 之后,<div>元素将得到一个“点击”事件。 等等 – 一直到<body>元素。 这就是jQuery将会捕获事件的地方,并且看看是否有任何适用于引发事件的元素的“活动”处理程序。 整齐!

最后, .delegate方法。 它只需要你的元素的所有孩子符合给定的select器,并附加一个“活的”处理程序给他们。 看一看:

 $("table").delegate( "td", "click", function() { alert( "Click!" ); } ); // Is equivalent to: $("table").each( function() { $(this).find( "td" ).live( "click", function() { alert( "Click!" ); } ); } ); 

有问题吗?

从jQuery 1.7开始,.live()方法已被弃用。 如果您使用的jQuery版本<1.7,而不是正式推荐使用.delegate()over .live()。

.live()现在已经被replace为.on()。

最好直接去jQuery网站了解更多信息,但是这里是.on()方法的当前版本:

 .on( events [, selector] [, data], handler(eventObject) ) .on( events-map [, selector] [, data] ) 

http://api.jquery.com/on/

$().click(fn) and $().bind('click', fn)一见钟情,但是$.bind版本更强大,原因有二:

  1. $().bind()允许你分配一个处理程序给多个事件,例如$().bind('click keyup', fn)
  2. $().bind()支持命名空间事件 – 一个强大的function,如果你想删除(取消绑定)只有某些元素绑定的事件处理程序 – 阅读更多命名空间事件

现场vs委托:这已经在其他答复中得到了回答。

这是阅读API可能帮助的地方。 然而,我知道我的头顶,所以你可以继续懒惰(耶!)。

 $('#something').click(fn); $('#something').bind('click',fn); 

这里没有什么区别(我知道)。 .click只是一个便利/辅助方法.bind('click'

 // even after this is called, all <a>s in // <div class="dynamic_els"> will continue // to be assigned these event handlers $('div.dynamic_els a').live('click',fn); 

这是非常不同的,因为.live会将事件添加到您传入的select器(您不在此处),并在插入/删除节点时继续查看DOM

 $('#some_element').delegate('td','click',fn); 

这只是因为你分配事件处理程序的方式不同。 .delegate以DOM事件冒泡为中心。 其基本原理是每个事件都会通过DOM树向上冒泡,直到它到达根元素( documentwindow<html><body> ,我记不起来了)。

无论哪种方式,你绑定一个onclick处理程序到$('#some_element')的所有<td> s(你必须指定一个select器,尽pipe你可以说$(document) )。 当其中一个孩子被点击时,事件会冒泡到<td> 。 然后你可以提取事件的源代码元素(jQuery自动为你做的)。

当有大量的元素时,这是非常有用的,而且只有less数(或一个中心)的点才能使这些事件通过。 这样可以节省浏览器的工作量和内存,将这些事件处理程序整合到更less的对象中。