当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的。而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢?

准备知识:

当我们在开始的时候,有些知识是必须具备的:

DOM树

下图仅仅是一个示例,这是一个在browser环境下的一棵模拟DOM树,在下面的代码中仅起到演示的作用:

Event bubbling (aka event propagation)冒泡

我们的页面可以理解为一棵DOM树,当我们在叶子结点上做什么事情的时候(如click一个a元素),如果我们不人为的设置stopPropagation(Moder Browser), cancelBubble(IE),那么它的所有父元素,祖宗元素都会受之影响,它们上面绑定的事件也会产生作用。看一个示例:

$('a').bind('click', function() { alert("That tickles!") });

当我们在a 上面点击的时候,首先会触发它本身所绑定的click事件,然后会一路往上,触发它的父元素,祖先元素上所有绑定的click事件,就像下图演示的那样。

示例HTML

为了对下面的代码进行演示,添加一些HTML代码:

<ul id="members" data-role="listview" data-filter="true">
<!-- ... more list items ... -->
<li>
<a href="detail.html?id=10">
<h3>John Resig(jQuery的作者)</h3>
<p><strong>jQuery Core Lead</strong></p>
<p>Boston, United States</p>
</a>
</li>
<!-- ... more list items ... -->
</ul>

Bind():

.bind()是最直接的绑定方法 ,会绑定事件类型和处理函数到DOM element上, 这个方法是存在最久的,而且也很好的解决了浏览器在事件处理中的兼容问题。但是这个方法有一些performance方面的问题,看下面的代码:

/* The .bind() method attaches the event handler directly to the DOM
element in question ( "#members li a" ). The .click() method is
just a shorthand way to write the .bind() method. */ $( "#members li a" ).bind( "click", function( e ) {} );
$( "#members li a" ).click( function( e ) {} );

上面的两行代码所完成的任务都是一致的,就是把event handler加到全部的匹配的<a>元素上。这里存在着一些效率方面的问题,一方面,我们隐式地把click handler加到所有的a标签上,这个过程是昂贵的;另一方面在执行的时候也是一种浪费,因为它们都是做了同一件事却被执行了一次又一次(比如我们可以把它hook到它们的父元素上,通过冒泡可以对它们中的每一个进行区分,然后再执行这个event handler)。

优点:

  • 这个方法提供了一种在各种浏览器之间对事件处理的兼容性解决方案
  • 非常方便简单的绑定事件到元素上
  • .click(), .hover()...这些非常方便的事件绑定,都是bind的一种简化处理方式
  • 对于利用ID选出来的元素是非常好的,不仅仅是很快的可以hook上去(因为一个页面只有一个id),而且当事件发生时,handler可以立即被执行(相对于后面的live, delegate)实现方式

缺点:

  • 它会绑定事件到所有的选出来的元素上
  • 它不会绑定到在它执行完后动态添加的那些元素上
  • 当元素很多时,会出现效率问题
  • 当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题

.live()

.live()方法用到了事件委托的概念来处理事件的绑定。它和用.bind()来绑定事件是一样的。.live()方法会绑定相应的事件到你所选择的元素的根元素上,即是document元素上。那么所有通过冒泡上来的事件都可以用这个相同的handler来处理了。它的处理机制是这样的,一旦事件冒泡到document上,jQuery将会查找selector/event metadata,然后决定那个handler应该被调用。jquery 1.8.2的源码:

当handler在执行的时候,因为有冒泡的参与,确实会有一些延迟,但是绑定的时候是特别的快。

上面的code在和.bind()相比的时候有一个好处就是我们不需要在每个元素上再去绑定事件,而只在document上绑定一次就可以了。尽管这个不是最快的方式,但是确实是最少浪费的。

优点:

  • 这里仅有一次的事件绑定,绑定到document上而不像.bind()那样给所有的元素挨个绑定
  • 那些动态添加的elemtns依然可以触发那些早先绑定的事件,因为事件真正的绑定是在document上
  • 你可以在document ready之前就可以绑定那些需要的事件

缺点:

  • 从1.7开始已经不被推荐了,所以你也要开始逐步淘汰它了。
  • Chaining没有被正确的支持
  • 当使用event.stopPropagation()是没用的,因为都要到达document
  • 因为所有的selector/event都被绑定到document, 所以当我们使用matchSelector方法来选出那个事件被调用时,会非常慢
  • 当发生事件的元素在你的DOM树中很深的时候,会有performance问题

.Delegate()

.delegate()有点像.live(),不同于.live()的地方在于,它不会把所有的event全部绑定到document,而是由你决定把它放在哪儿。而和.live()相同的地方在于都是用event delegation.

优点:

  • 你可以选择你把这个事件放到那个元素上了
  • chaining被正确的支持了
  • jQuery仍然需要迭代查找所有的selector/event data来决定那个子元素来匹配,但是因为你可以决定放在那个根元素上,所以可以有效的减小你所要查找的元素。
  • 可以用在动态添加的元素上

缺点:

  • 需要查找那个那个元素上发生了那个事件了,尽管比document少很多了,不过,你还是得浪费时间来查找。

.On()

其实.bind(), .live(), .delegate()都是通过.on()来实现的,.unbind(), .die(), .undelegate(),也是一样的都是通过.off()来实现的,这是1.8.2的源码:

看一下,我们用如何用.on()来改写前面通过 .bind(), .live(), .delegate()所注册的事件:

/* The jQuery .bind(), .live(), and .delegate() methods are just one
line pass throughs to the new jQuery 1.8.2 .on() method */ // Bind
$( "#members li a" ).on( "click", function( e ) {} );
$( "#members li a" ).bind( "click", function( e ) {} ); // Live
$( document ).on( "click", "#members li a", function( e ) {} );
$( "#members li a" ).live( "click", function( e ) {} ); // Delegate
$( "#members" ).on( "click", "li a", function( e ) {} );
$( "#members" ).delegate( "li a", "click", function( e ) {} );

优点:

  • 提供了一种统一绑定事件的方法
  • 仍然提供了.delegate()的优点,当然如果需要你也可以直接用.bind()

缺点:

  • 也许会对你产生一些困扰,因为它隐藏了一前面我们所介绍的三种方法的细节。

结论:

  • 用.bind()的代价是非常大的,它会把相同的一个事件处理程序hook到所有匹配的DOM元素上
  • 不要再用.live()了,它已经不再被推荐了,而且还有许多问题
  • .delegate()会提供很好的方法来提高效率,同时我们可以添加一事件处理方法到动态添加的元素上。
  • 我们可以用.on()来代替上述的3种方法
 
 

转 jQuery 中bind(),live(),delegate(),on() 区别的更多相关文章

  1. jQuery 中bind(),live(),delegate(),on() 区别(转)

    当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...

  2. jquery实现input输入框实时输入触发事件代码 ---jQuery 中bind(),live(),delegate(),on() 区别

    复制代码 代码如下: <input id="productName" name="productName" value="" /> ...

  3. jQuery中.bind() .live() .delegate() .on()区别

    $(selector).bind(event,data,function) $(selector).live(event,data,function)//jquery1.9版本以下支持,jquery1 ...

  4. jQuery 中bind(),live(),delegate(),on() 区别

    on()来改写通过 .bind(), .live(), .delegate()所注册的事件 /* The jQuery .bind(), .live(), and .delegate() method ...

  5. Jquery中bind和live的区别

    Jquery中绑定事件有三种方法:以click事件为例 (1)target.click(function(){}); (2)target.bind("click",function ...

  6. jQuery中bind,live,delegate与one方法的用法及区别解析

    bind( )方法用于将一个处理程序附加到每个匹配元素的事件上并返回jQuery对象. .bind(eventType[, evnetData], Handler(eventObject)) 其中,参 ...

  7. jQuery中.bind() .live() .delegate() .on()的区别 和 三种方式写光棒事件 动画

    地狱的镰刀 bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数. $("a").bind("click",function(){ ...

  8. jquery中bind,live,delegate,on的区别

    这几种方法都是绑定事件用到的,但是他们之间有些差别 bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数 例如: <ul> <a href=" ...

  9. 【转】jQuery中.bind() .live() .delegate() .on()的区别

    bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数 $("a").bind("click",function(){alert(& ...

随机推荐

  1. 百度EChart3初体验

    由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...

  2. Oracle 内置sql函数大全

    F.1字符函数--返回字符值 这些函数全都接收的是字符族类型的参数(CHR除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.字符函数的返回类型所受的限制和基本数据 ...

  3. window下使用Redis Cluster部署Redis集群

    日常的项目很多时候都需要用到缓存.redis算是一个比较好的选择.一般情况下做一个主从就可以满足一些比较小的项目需要.在一些并发量比较大的项目可能就需要用到集群了,redis在Windows下做集群可 ...

  4. 网站美化常见CSS

    伴随网络时代日新月异的发展,用户不仅仅满足于软件系统的功能需求,对软件系统的页面显示效果以及交互模式的要求也逐渐提高.尤其是展示性质的平台页面对于界面美化效果要求更高,有一句话说的好:Html是结构, ...

  5. C++ 最小化到托盘

    #define WM_SHOWTASK (WM_USER + 1) void CTestDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID &a ...

  6. Redis高可用集群方案——哨兵

    本篇文章版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文系列地址http://www.cnblogs.com/tdws/tag/NoSql/ 本人之前有篇文章,讲到了redis主从复制,读写分 ...

  7. C#的委托

    之前本人一直在写一些相对比较基础的C#代码,现在做了一段时间项目了,遇到更麻烦的问题,比如今天要讨论的委托和事件,这个算是C#进阶篇的内容吧.现在自己就把这些天所学习的和自己所理解的和大家分享.有错请 ...

  8. SharePoint Designer 2013 连接 Office 365 必需安装2个SP

    第一个: 32位电脑安装链接:http://www.microsoft.com/downloads/details.aspx?FamilyId=278a31eb-0cf9-4b30-a670-9c9d ...

  9. 磨刀不误砍柴工——VS生成事件

    如果说磨刀不误砍柴工,同样用好Visual Studio,会大大增加咱.NET程序猿效率.本文说的就是Visual Studio中的生成事件,在解决方案下右击某个项目然后选择 “属性” 打开窗口后即可 ...

  10. iOS多线程之8.NSOPeration的其他用法

      本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration. 1.添加依赖 - (void)addDependency:(NSOperation * ...