详解jQuery中 .bind() vs .live() vs .delegate() vs .on() 的区别

转载自:http://zhuzhichao.com/2013/12/differences-between-jquery-bind-vs-live/

我见过很多开发者很困惑关于jQuery中的.bind(), .live(), .delegate() 和 .on() 的使用以及它们的不同。

如果你没有耐心或者只想看到总结的话,请直接跳转到结尾。

在我们深入了解这些方法之前,先准备好HTML代码。

[javascript] view plain copy

  1. <pre>
  2. <ul id="members" data-role="listview" data-filter="true"><!-- ... more list items ... -->
  3. <li>
  4. <h3>John Resig</h3>
  5. <a href="detail.html?id=10">
  6. <strong>jQuery Core Lead</strong>
  7. Boston, United States
  8. </a></li>
  9. <!-- ... more list items ... --></ul>
  10. </pre>

.bind()

.bind()注册的事件直接指向相对应的DOM元素。这个方法从jQuery 1.0都有了,并且这个方法能够很酷的处理跨浏览器的事件绑定问题。对,这个方法用起来很方便。但是问题来了,就是各种各样的性能问题,如下:

[javascript] view plain copy

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

优点

  • 跨浏览器
  • 非常方便和快捷地绑定事件
  • 简单的实现方法(.click() .hover() ,etc…)让它用起来很方便
  • 对于简单的ID选择器来说,使用.bind()不仅方便,而且当触发这个事件的时候能够即时响应。

缺点

  • 这个方法会附加相同的处理程序到每一个匹配到的元素上
  • 对于动态添加的属于匹配到的元素,不会被触发事件的
  • 性能问题,对于处理大量的匹配元素的时候
  • 如果在页面加载前要处理添加事件的话,会影响加载效率的

.live()

.live()方法使用的是事件委托的概念来执行所谓的“神奇方法”。调用.live()方法看起来和调用.bind()方法一样,非常方便。但是他们下面的实现原理却不同。.live()方法附加事件处理程序到根一级的document上来关联匹配到的元素和事件信息。通过注册事件处理程序到document上来允许事件处理程序通过冒泡来绑定事件和匹配的元素(译者:注意,事件其实在document上的)。一旦事件冒泡到document的时候,jQuery判断选择器和事件处理程序是否有匹配到的,如果有的话,则调用对应的事件处理程序。很明显的会在用户使用的过程中有性能问题,但是在绑定注册的时候是非常的迅速的。

[javascript] view plain copy

  1. Code example:
  2. /* The .live() method attaches the event handler to the root level
  3. document along with the associated selector and event information
  4. ( "#members li a" & "click" ) */
  5. $( "#members li a" ).live( "click", function( e ) {} );

优点

  • 相对于.bind()的循环注册很多次事件处理程序来说,.live()只注册一次事件处理程序
  • 从.bind()更新到.live()的方法对程序更改很少,只需要替换“bind”为”live”
  • 对于动态添加的属于匹配到的元素,也能够“神奇”的执行处理程序
  • 在document元素没有全部加载完之前都能够几乎不花时间地绑定并触发事件

缺点

  • 此方法在jQuery1.7的时候已经废除,你应该逐步从你的代码中替换掉该方法
  • 链接不能够正常的支持这个方法
  • 这个方法被抛弃是因为它只能够绑定事件处理程序到document上
  • event.stopPropagation()不再有效了,因为事件已经委托到了document上了
  • 由于所有的选择器和事件信息都是附加到了document上的,所以一个确定的事件要触发,必须通过大量的存储信息来匹配到
  • 由于事件都是委托到了document上的,所以如果DOM太深的话,会影响到性能的

.delegate()

.delegate()方法的行为有点类似.live()。但是不是把选择器和事件的信息附加到了document上,而是可以自行选择它要附加的DOM元素,这个技术可以让事件的委托正常工作。 如果你跳过了.live()的介绍和分析,请先跳回去读一下,接着我才能向你表述清楚下面的逻辑

[javascript] view plain copy

  1. Code example:
  2. /*.delegate()的处理方法类似.live(),但是不是将事件处理程序附加到了document上,而是可以选择它在哪里("#members")。选择器和事件信息("li a" 和 "click")将会附加到“#members”元素上。 */
  3. $( "#members" ).delegate( "li a", "click", function( e ) {} );

.delegate()方法是非常强大的。上面的代码会将事件处理程序以及选择器和事件信息附加到”#members”上。这个当然要比.live()将这些内容附加到document上有效的多了。另外有很多其他的一年问题也通过.delegate()这个方法解决了。请参阅下列大纲的详细列表。

优点

  • 可以自由选择附加的选择器和事件信息的位置
  • 链接也可以有效的支持了
  • jQuery仍然需要循环访问选择器和事件数据来确定匹配,但是因为能够选择这些信息附加的位置,所以通过匹配的量小很多了
  • 由于这种技术使用了事件委托,所以它能很好的动态处理添加到DOM元素
  • 如果你委托事件到了document上,你也可以在document全部准备完之前绑定和调用

缺点

  • 方法从.bind()更改到.delegate()比较麻烦
  • 如果把选择器和事件数据附加到了document上,仍然需要很多的匹配信息,但是相对于.live()的存储量要小很多了

.on()

你知道jQuery中的.bind() .live 和 .delegate()方法都是通过同一个新方法实现的–.on() (在jQuery1.7后),下面的代码片段来自jQuery 1.7.1 codebase in GitHub

[javascript] view plain copy

  1. Code example:
  2. // ... more code ...
  3. bind: function( types, data, fn ) {
  4. return this.on( types, null, data, fn );
  5. },
  6. unbind: function( types, fn ) {
  7. return this.off( types, null, fn );
  8. },
  9. live: function( types, data, fn ) {
  10. jQuery( this.context ).on( types, this.selector, data, fn );
  11. return this;
  12. },
  13. die: function( types, fn ) {
  14. jQuery( this.context ).off( types, this.selector || "**", fn );
  15. return this;
  16. },
  17. delegate: function( selector, types, data, fn ) {
  18. return this.on( types, selector, data, fn );
  19. },
  20. undelegate: function( selector, types, fn ) {
  21. return arguments.length == 1 ?
  22. this.off( selector, "**" ) :
  23. this.off( types, selector, fn );
  24. },
  25. // ... more code ...

这就意味着这个新方法的用法可以像下面这样

[javascript] view plain copy

  1. Code example:
  2. /* The jQuery .bind(), .live(), and .delegate() methods are just one
  3. line pass throughs to the new jQuery 1.7 .on() method */
  4. // Bind
  5. $( "#members li a" ).on( "click", function( e ) {} );
  6. $( "#members li a" ).bind( "click", function( e ) {} );
  7. // Live
  8. $( document ).on( "click", "#members li a", function( e ) {} );
  9. $( "#members li a" ).live( "click", function( e ) {} );
  10. // Delegate
  11. $( "#members" ).on( "click", "li a", function( e ) {} );
  12. $( "#members" ).delegate( "li a", "click", function( e ) {} );

你会注意到,具体取决于我如何调用.on()方法来更改它的执行过程。你可以考虑“重载”.on()方法来具有不同的效果。这个方法给API带来了很多的一致性,并希望减少那些方法的混淆。

优点

  • 为各种事件绑定方法带来了统一性
  • 简化了jQuery代码库,并删除一个界别的重定向,因为通过调用这个方法实现了 .bind() .live() 和 .delegate()
  • 仍然提供了好用的.delegate()方法,但是也仍然对.bind()方法提供了支持

缺点

  • 因为调用这个方法的各个形式,会带来一些混乱

总结

如果你已经对各种类型的事件绑定方法混淆的神志不清的话也别担心,这是因为历史遗留问题和API在随着时间的推移导致的。有些人认为这些方法作为魔法方法,但是一旦你发现他们如何工作的将会更好的利于你的项目。

从这篇文章中应该记住的要点:

  • 使用.bind()方法是很浪费资源的,因为它要匹配选择器中的每一项并且挨个设置相同的事件处理程序
  • 建议停止使用.live()方法,因为它已经被弃用了,由于他有很多的问题
  • .delegate()方法“很划算”用来处理性能和响应动态添加元素的时候
  • 新的.on()方法主要是可以实现.bind() .live() 甚至 .delegate()的功能
  • 建议使用.on()方法,如果你的项目使用了1.7+的jQuery的话
时间: 2024-10-22 19:42:27

详解jQuery中 .bind() vs .live() vs .delegate() vs .on() 的区别的相关文章

jQuery:详解jQuery中的事件(一)

之前用过一些jQuery的动画和特效,但是用到的部分也不超过10%的样子,感觉好浪费啊——当然浪费的不是jQuery,而是Web资源.后来就想深入研究下jQuery的内部机理,读过两遍jQuery源代码,但是自觉还差的好远,跟好多大神(比如阮一峰)的理解还是有很大差距.现在就一点一点积累自己的知识体系,记录自己学到的和自己所理解的jQuery. JavaScript和HTML之间的交互式通过用户和浏览器操作页面时引发的事件机制来处理的.当文档或者它的某些元素发生某些变化或操作时,浏览器就会自动生

$.ajax()方法详解 jquery中的ajax方法

jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持. 3.timeout: 要求为Number类型的参数,设置请求超时时间(毫秒).此设置将覆盖$.ajaxSetup()方法的全局设置. 4.async: 要求为Boolean类型的参数,默

jQuery中bind方法和live方法区别解析

Javascript中的事件有它的独特性,有默认的执行事件,例如冒泡就是其中的一个.在很多比较复杂的应用程序中,停止事件的冒泡或捕获在程序开发当中是十分有用的,而在IE中有它的独特方式来阻止事件的冒泡(和其它浏览器方式不同). 以下给出一种通用的方式来实现阻止事件的冒泡,该通用方式接受一个参数[传递到事件处理程序中的事件对象],该函数处理取消事件冒泡的两种方式:标准的W3C方式和非标准的IE方式: 什么是事件冒泡[又称为事件传播]:当我们点击一个元素时,它会触发bind在该元素上的click事件

jQuery Mobile的默认配置项详解,jQuery Mobile的中文配置api,jQuery Mobile的配置说明,配置大全

学习jQuery Mobile也有一段时间了,越来越上手了,也越来越喜欢他了.我根本就没有理由拒绝他的好.这里我有分享一下我对它的配置项的使用说明一下. 看代码解释: $(document).live("pageinit",function(event){ $.mobile.loadingMessage = "正在加载数据,请稍候......"; $.mobile.pageLoadErrorMessage="很抱歉,系统好像再打小瞌睡......"

详解javascript中的this对象

详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的设计模式来实现面向对象的编程,其中this "指针"就是实现面向对象的一个很重要的特性.但是this也是Javascript中一个非常容易理解错,进而用错的特性.特别是对于接触静态语言比较久了的同志来说更是如此. 示例说明 我们先来看一个最简单的示例: <script type=&q

详解C#中Socket通信(一):实现连接

第一步:实现连接 客户端连接代码: private void connect2Server() { Socket clientSocket; //服务器地址 IPAddress ip = IPAddress.Parse("192.168.1.136"); //服务器节点 IPEndPoint iep = new IPEndPoint(ip, 9004); //通信实例 clientSocket = new Socket(AddressFamily.InterNetwork, Socke

详解Android中那些酷炫返回方式的实现

Android手机都会有返回键,不管是实体键,还是虚拟键.Android用户主要也都是通过这个返回键操控页面返回方式的,不比IOS逼格甚高的只保留一个操作键.这种方式是最普遍的返回方式,还有一种也是比较常见的,那就是页面内部自己响应.绝大多数APP每个页面的设计图顶部左侧都会有一个返回键图标,偶尔也有奇葩的设计放在底部左侧,点击这个图标即finish掉当前页面.简单的介绍完了最常见的两种方式,下面为大家介绍两种更友好的交互方式. 拿大家比较常用的三款社交软件的交互来说.腾讯微博的返回方式除去上述

CSS学习笔记(9)--详解CSS中:nth-child的用法

详解CSS中:nth-child的用法 前端的哥们想必都接触过css中一个神奇的玩意,可以轻松选取你想要的标签并给与修改添加样式,是不是很给力,它就是":nth-child". 下面我将用几个典型的实例来给大家讲解:nth-child的实际用途: Tips:还用低版本的IE浏览器的哥们请绕过! :nth-child(2)选取第几个标签,"2可以是你想要的数字" .demo01 li:nth-child(2){background:#090} :nth-child(n

详解HTTP中get和post的区别

1.详解HTTP中GET和POST的区别 http://www.jellythink.com/archives/806 2.HTTP 方法:GET 对比 POST http://www.cnblogs.com/liu-ke/p/4198815.html