详解jQuery中 .bind() vs .live() vs .delegate() vs .on() 的区别
转载自:http://zhuzhichao.com/2013/12/differences-between-jquery-bind-vs-live/
我见过很多开发者很困惑关于jQuery中的.bind(), .live(), .delegate() 和 .on() 的使用以及它们的不同。
- <pre>
- <ul id="members" data-role="listview" data-filter="true"><!-- ... more list items ... -->
- <li>
- <h3>John Resig</h3>
- <a href="detail.html?id=10">
- <strong>jQuery Core Lead</strong>
- Boston, United States
- </a></li>
- <!-- ... more list items ... --></ul>
- </pre>
.bind()
.bind()注册的事件直接指向相对应的DOM元素。这个方法从jQuery 1.0都有了,并且这个方法能够很酷的处理跨浏览器的事件绑定问题。对,这个方法用起来很方便。但是问题来了,就是各种各样的性能问题,如下:
- Code example:
- /* 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 ) {} );
优点
- 跨浏览器
- 非常方便和快捷地绑定事件
- 简单的实现方法(.click() .hover() ,etc…)让它用起来很方便
- 对于简单的ID选择器来说,使用.bind()不仅方便,而且当触发这个事件的时候能够即时响应。
缺点
- 这个方法会附加相同的处理程序到每一个匹配到的元素上
- 对于动态添加的属于匹配到的元素,不会被触发事件的
- 性能问题,对于处理大量的匹配元素的时候
- 如果在页面加载前要处理添加事件的话,会影响加载效率的
.live()
.live()方法使用的是事件委托的概念来执行所谓的“神奇方法”。调用.live()方法看起来和调用.bind()方法一样,非常方便。但是他们下面的实现原理却不同。.live()方法附加事件处理程序到根一级的document上来关联匹配到的元素和事件信息。通过注册事件处理程序到document上来允许事件处理程序通过冒泡来绑定事件和匹配的元素(译者:注意,事件其实在document上的)。一旦事件冒泡到document的时候,jQuery判断选择器和事件处理程序是否有匹配到的,如果有的话,则调用对应的事件处理程序。很明显的会在用户使用的过程中有性能问题,但是在绑定注册的时候是非常的迅速的。
- Code example:
- /* The .live() method attaches the event handler to the root level
- document along with the associated selector and event information
- ( "#members li a" & "click" ) */
- $( "#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()的介绍和分析,请先跳回去读一下,接着我才能向你表述清楚下面的逻辑
- Code example:
- /*.delegate()的处理方法类似.live(),但是不是将事件处理程序附加到了document上,而是可以选择它在哪里("#members")。选择器和事件信息("li a" 和 "click")将会附加到“#members”元素上。 */
- $( "#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…
- Code example:
- // ... more code ...
- bind: function( types, data, fn ) {
- return this.on( types, null, data, fn );
- },
- unbind: function( types, fn ) {
- return this.off( types, null, fn );
- },
- live: function( types, data, fn ) {
- jQuery( this.context ).on( types, this.selector, data, fn );
- return this;
- },
- die: function( types, fn ) {
- jQuery( this.context ).off( types, this.selector || "**", fn );
- return this;
- },
- delegate: function( selector, types, data, fn ) {
- return this.on( types, selector, data, fn );
- },
- undelegate: function( selector, types, fn ) {
- return arguments.length == 1 ?
- this.off( selector, "**" ) :
- this.off( types, selector, fn );
- },
- // ... more code ...
这就意味着这个新方法的用法可以像下面这样
- Code example:
- /* The jQuery .bind(), .live(), and .delegate() methods are just one
- line pass throughs to the new jQuery 1.7 .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 ) {} );
优点
- 为各种事件绑定方法带来了统一性
- 简化了jQuery代码库,并删除一个界别的重定向,因为通过调用这个方法实现了 .bind() .live() 和 .delegate()
- 仍然提供了好用的.delegate()方法,但是也仍然对.bind()方法提供了支持
缺点
- 因为调用这个方法的各个形式,会带来一些混乱
总结
如果你已经对各种类型的事件绑定方法混淆的神志不清的话也别担心,这是因为历史遗留问题和API在随着时间的推移导致的。有些人认为这些方法作为魔法方法,但是一旦你发现他们如何工作的将会更好的利于你的项目。
- 使用.bind()方法是很浪费资源的,因为它要匹配选择器中的每一项并且挨个设置相同的事件处理程序
- 建议停止使用.live()方法,因为它已经被弃用了,由于他有很多的问题
- .delegate()方法“很划算”用来处理性能和响应动态添加元素的时候
- 新的.on()方法主要是可以实现.bind() .live() 甚至 .delegate()的功能
- 建议使用.on()方法,如果你的项目使用了1.7+的jQuery的话
详解jQuery中 .bind() vs .live() vs .delegate() vs .on() 的区别的更多相关文章
- jQuery中bind,live,delegate,on的区别
bind(),live()都是调用on()函数,只不过传递的参数不同. 一.$(selector).bind(event,data,fn); $('#J_btn').bind('click',func ...
- jQuery:详解jQuery中的事件(二)
上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...
- Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
简介 最近了解到很多网页开发者对jquery中的 .bind() .live() .delegate() 和 .on() 方法存在很多的疑惑.这些疑惑通常是关于它们之间真正的区别是什么啊,什么时候该使 ...
- jQuery:详解jQuery中的事件(一)
之前用过一些jQuery的动画和特效,但是用到的部分也不超过10%的样子,感觉好浪费啊——当然浪费的不是jQuery,而是Web资源.后来就想深入研究下jQuery的内部机理,读过两遍jQuery源代 ...
- $.ajax()方法详解 jquery中的ajax方法
jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...
- Jquery中bind和live.one,delegate的区别
Jquery中绑定事件有三种方法:以click事件为例 (1)target.click(function(){}); (2)target.bind("click",function ...
- jQuery的.bind()、.live()和.delegate(),on之间区别
基本要素 51CTO推荐专题:jQuery从入门到精通 DOM树 首先,可视化一个HMTL文档的DOM树是很有帮助的.一个简单的HTML页面看起来就像是这个样子: 事件冒泡(又称事件传播) 当我们点击 ...
- Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解(转)
转自:https://www.jb51.net/article/120018.htm
- $.ajax()方法详解 jquery
$.ajax()方法详解 jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...
随机推荐
- Sql Server中一次更新多列数据
UPATE yourTableName SET column1 = xx, column2 = yy , column3 = zz WHERE yourCondition 举个例子,比如有这样一张表: ...
- typescript 添加基础类型的扩展方法
以时间转换为案例: //声明接口,也是在声明date这个基础类型要定义一个format的扩展方法,不写接口声明会报错 interface Date { Format(fmt:string):strin ...
- 特殊权限的介绍 SGID SUID SBIT
Set UID 当s这个标志出现在文件所有者的x权限上时,如/usr/bin/passwd这个文件的权限状态:“-rwsr-xr-x.”,此时就被称为Set UID,简称为SUID.那么这个特殊权限的 ...
- luogu P1503 鬼子进村
嘟嘟嘟 线段树好题. 其实挺水的,想暴力怎么做:每一次从这个点开始向两边扩,直到遇到第一个摧毁的房屋. 那么把暴力改成倍增,然后线段树查询区间和是否为0.时间复杂度O(nlog2n). 题解好像有线段 ...
- VMWARE下CentOS7虚拟机网络配置
注:本文仅针对新装的虚拟机,#ip addr 获取不到ip信息,无法连接网络的情况提供一种参考解决方案. 1.左上角点击“编辑”->“虚拟网络编辑器”.新建一个NAT模式的网络. 2.配置虚拟机 ...
- 设置IE浏览器的默认下载路径
实现效果: 知识运用: Default Download Directory键 实现代码: private void button2_Click(object sender, EventArgs e) ...
- Android学习笔记_10_ContentProvider内容提供者的使用
一.使用ContentProvider共享数据 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.以前我们学习过文件的操作模式,通过指定文 ...
- mac install PyQt5
1. install brew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/insta ...
- 关于ProjectServer定制化项目中心页面
ProjectServer界面很多客户接受不了,随便用户可以根据自己需要展示页面,但大多数国内用户喜欢确定的样式,我就是要这样的页面,不要个人定制. 那只有自己再做一个项目中心的webpart嵌入,对 ...
- 分享一个展示文章列表的CSS样式
最近在帮朋友处理一个网站前端显示文章列表的时候,其中有个变通的思路,现整理出来留给有需要的朋友参考及自己备忘. 显示效果为:标题左对齐,日期右对齐. 标题和日期中间用常规的原点(“.”) 代替,显示效 ...