Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解
简介
最近了解到很多网页开发者对jquery中的 .bind() .live() .delegate() 和 .on() 方法存在很多的疑惑。这些疑惑通常是关于它们之间真正的区别是什么啊,什么时候该使用它们啊。下面本文将给大家详细介绍这四个方法之间的区别,分别对每个方法都进行了详细的介绍,话不多说,来一起看看详细的介绍:
在我们深入了解这些方法之前,我们先来一段常见的的HTML,作为我们编写jquery示例方法使用的样本。
|
1
2
3
4
5
6
7
8
9
10
11
|
<ul id="members" data-role="listview" data-filter="true"> <!-- ... 其他li ... --> <li> <a href="detail.html?id=10" rel="external nofollow" > <h3>John Resig</h3> <p><strong>jQuery Core Lead</strong></p> <p>Boston, United States</p> </a> </li> <!-- ... 其他li ... --></ul> |
使用Bind方法
.bind()方法将事件类型和一个事件处理函数直接注册到了被选中的DOM元素中。这个方法被使用得最久,在此期间,它很好的解决了各种跨浏览器的问题。当使用它来连接事件处理函数时,它仍然非常简洁,但是也存在着一些性能方面的问题,将在下面罗列出来。
|
1
2
3
4
5
6
|
/* .bind() 方法将事件类型和一个事件处理函数直接注册到了被选中的DOM元素中。 .click() 方法只是.bind() 方法的简写。*/$( "#members li a" ).bind( "click", function( e ) {} ); $( "#members li a" ).click( function( e ) {} ); |
.bind()方法将会把事件处理函数连接到所有匹配的a标签。这种方式并不好。这样做的话,它不仅在所有匹配的元素中隐含地迭代附加事件处理函数,而且这些操作非常浪费(多余),因为这些相同的事件处理函数是被一遍一遍的重复的添加到所有匹配的标签上。
优点:
- 适用于各种浏览器
- 连接事件处理函数非常方便快捷
- 可以使用
.click(),.hover()等简写方法来更方面地连接事件处理函数 - 对于一个简单的ID选择器,使用
.bind()方法不仅可以很快地连接事件处理函数,而且当事件被触发时, 事件处理函数几乎是马上就被调用了
缺点:
- 这样方法会将所有的事件处理函数附加到所有匹配的元素
- 不可以动态地匹配相同选择器的元素
- 当操作大量匹配的元素时会有性能方面的问题
- 附加操作是在前期完成的,这可能导致页面加载时存在性能问题
使用Live方法
.live()方法使用了事件委托的概念来实施其所谓的“魔法”。你调用live()方法的方式就像是调用bind()方法那样方便。然而在这表面之下, .live()方法与前者的实现方式大不相同。 .live()方法将与事件处理函数关联的选择器和事件信息一起附加到文档的根级元素(即document)。通过将事件信息注册到document上,这个事件处理函数将允许所有冒泡到document的事件调用它(例如委托型、传播型事件)。一旦有一个事件冒泡到document元素上,Jquery会根据选择器或者事件的元数据来决定哪一个事件处理函数应该被调用,如果这个事件处理函数存在的话。这个额外的工作将会在用户交互时对性能方面造成一定的影响,但是初始化注册事件的过程相当地快。
|
1
2
3
4
|
/* 方法将与事件处理函数关联的选择器和事件信息一起附加到文档的根级元素(即document) ( "#members li a" & "click" ) */$( "#members li a" ).live( "click", function( e ) {} ); |
.bind()这个例子与上面bind()方法的例子对比的话有一个优点在于它仅仅把事件处理函数附加到document元素一次,而不是很多次。这样不仅更快,而且还减少了性能的浪费。然而,使用这个方法也会带来很多问题,下面将一一列出。
优点:
- 所有的事件处理函数都只会被注册一次,而不是像
bind()那样进行多次注册 - 将
bind()方法升级到live()方法非常方便,你仅需要将"bind"替代为"live"就可以了 - 那些被动态添加到DOM的元素也将被神奇的匹配到,因为真实的事件信息是被注册到document元素上的
- 你可以在文档加载完之前连接事件处理函数,这样可以帮助你更好地利用你可能没有用的时间
缺点:
- 这个方法在Jquery 1.7以后的版本被弃用了,你应该在你的代码里逐步放弃使用它
- 使用这个方法时链式操作没有得到正确的支持,可能会出现某些错误
- 所做的匹配操作基本上没用因为它只用于在document元素上注册事件处理函数
- 使用
event.stopPropogation()方法将会没用,因为事件总是已经被委托到了document元素上 - 因为所有的选择器或者事件信息都被附加到document元素上了,所以一旦有一个事件要调用某个事件处理函数,Jquery会在一大堆储存的元数据中使用matchesSelector方法来决定哪一个事件处理函数将会被调用,如果这个函数有的话。
- 因为你所连接的事件总是被委托到document上,所如果你的DOM的层级很深的话,这会导致一定的性能问题
使用Delegate方法
.delegate()方法与live()方式实现方式相类似,它不是将选择器或者事件信息附加到document,而是让你指定附加的元素。就像是live()方法一样,这个方法使用事件委托来正确地工作。
如果你跳过了前面关于 .live() 方法的介绍,你可能要回去重新看看它,因为这里涉及到之前我所阐述的一些内部逻辑
|
1
2
3
4
|
/* .delegate() 方法会将选择器和事件信息 ( "li a" & "click" ) 附加到你指定的元素上 ( "#members" )。*/$( "#members" ).delegate( "li a", "click", function( e ) {} ); |
.delegate()方法十分强大。在上面这个例子中,与事件处理函数关联的选择器和事件信息将会被附加到( #members" )这个元素上。这样做比使用live()高效多了,因为live()方法总是将与事件处理函数关联的选择器和事件信息附加到document元素上。另外,使用.delegate()方法解决许多其他问题。请参阅下方列出的详细信息。
优点:
- 你可以选择将选择器或者事件信息附加到指定的元素。
- 匹配操作实际上在前面并没有执行,而是用来注册到指定的元素。
- 链式操作可以得到正确的支持
- Jquery仍然需要迭代这些选择器或者事件信息来匹配元素,不过因为你可以选择哪一个元素作为根元素,所以筛选的量会大幅减少
- 因为这项技术使用了事件委托机制,它可以匹配到被动态地添加到DOM的元素
- 你可以在文档加载完之前连接事件处理函数
缺点:
- 从
.bind()方法不可以直接升级到.delegate()方法 - Jquery仍然需要使用marchesSelector方法在附加到指定根元素的选择器或者事件信息中筛选决定哪一个事件处理函数会被调用。然而,附加到指定根元素的元数据会比使用
live()方法的时候要小得多。 - 当操作大量匹配的元素时会有性能方面的问题
- 附加操作是在前期完成的,这可能导致页面加载时存在性能问题
使用On方法
你知道吗,在Jquery 1.7版本中.bind() , .live() 和.delegate()方法只需要使用.on()方法一种方式来调用它们。当然.unbind() , .die() 和.undelegate()方法也一样。一下代码片段是从Jquery 1.7版本的源码中截取出来的
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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 );} |
考虑到这一点,使用.on()方法看起来像以下方式一样...
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/* Jquery的 .bind() , .live() 和 .delegate() 方法只需要使用`.on()`方法一种方式来调用它们 */// 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 ) {} ); |
你可能注意到了,我如何使用.on()方法决定了它如何调用其他方法。你可以认为.on()方法被具有不同签名的方法”重载“了,而这些方法实现了不同的事件绑定的连接方式。 .on()方法的出现为API带来了很多方面的一致性,并希望让事情变得不那么混乱。
优点:
- 使各种事件绑定方法一致。
- 因为在Jquery源码中
.bind(),.live()和.delegate()方法实际上是调用了此方法,因此简化了jQuery代码库并删除了一级重定向。 - 这种方式仍然提供了使用
.delegate()方法的优点,并且仍然提供对.bind()方法的支持,如果你需要的话。
缺点:
- 给人带来了一些疑惑,因为方法的实际执行方式将根据你如何调用方法而改变。
总结
如果你对不同的绑定事件方法有所迷惑,那么不要担心,因为API发展了一段时间了,有很多前人的经验可以借鉴。也有很多人将这些方法视为魔法,不过一旦你了解了他们工作背后的原理,将帮助您了解如何更好地处理项目。
以下是这篇文章的精华所在...
- 使用
.bind()方法非常浪费性能因为它把同一个事件处理函数附加到了每一个匹配的元素上 - 你应该停止使用
.live()方法因为它被弃用了同时也会带来很多问题 - 使用
.delegate()方法会给你带来很多好处当你需要解决一些性能上的问题和对动态添加的元素作出处理 - 新的
.on()方法其实就是模拟.bind(),.live()和.delegate()实现的语法糖,具体取决于你如何调用它 - 新的方向是使用新的
.on()方法。先熟悉语法,并开始在你的所有的Jquery 1.7版本以上的项目使用它吧!
对于上面列举的优点或者缺点,你有新的补充吗?你最近开始使用delegate()方法了吗?你对新的.on()方法怎么看呢?把你的想法写到用评论告诉我吧!谢谢!
第一次翻译,文章中可能会出现一些不通顺的地方,希望得到大家的理解,毕竟我还是个学生啊!
好了,大概就这样,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持
Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解的更多相关文章
- Jquery中.bind()、.live()、.delegate()和.on()之间的区别详解(转)
转自:https://www.jb51.net/article/120018.htm
- jQuery 中bind(),live(),delegate(),on() 区别(转)
当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...
- 转 jQuery 中bind(),live(),delegate(),on() 区别
当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...
- jquery实现input输入框实时输入触发事件代码 ---jQuery 中bind(),live(),delegate(),on() 区别
复制代码 代码如下: <input id="productName" name="productName" value="" /> ...
- jQuery中.bind() .live() .delegate() .on()区别
$(selector).bind(event,data,function) $(selector).live(event,data,function)//jquery1.9版本以下支持,jquery1 ...
- jQuery 中bind(),live(),delegate(),on() 区别
on()来改写通过 .bind(), .live(), .delegate()所注册的事件 /* The jQuery .bind(), .live(), and .delegate() method ...
- JQuery中常用的$.get(),$.post(),$.ajax(),$.getJSON(),load()的详解与区别
背景:因为最近需要获取本地的数据件进行项目测试,需要用到JQuery实现数据文件的读取,但是由于对JQuery内的获取文件方式不太了解,这次趁着机会进行一下总结.因为该总结是本人根据平常的使用及网上的 ...
- JQuery的ready函数与JS的onload的区别详解
JQuery的ready函数与JS的onload的区别:1.执行时间window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行.$(document).ready()是DOM结构绘制 ...
- jQuery中bind,live,delegate与one方法的用法及区别解析
bind( )方法用于将一个处理程序附加到每个匹配元素的事件上并返回jQuery对象. .bind(eventType[, evnetData], Handler(eventObject)) 其中,参 ...
随机推荐
- Web大文件上传(断点续传)控件-Xproer.HttpUploader6-安装教程
安装教程: IE8控件安装教程 IE9控件安装教程 Firefox控件安装教程 Chrome控件安装教程 Chrome 45+控件安装教程 相关问题: 提示Runtime Error错误 360拦 ...
- spring mvc 入门程序
入门程序 1.环境准备 myeclipse Spring jar 2.前端控制器设置 (web.xml) 所有的*.action请求通过org.springframework.web.servlet. ...
- Javascript 控制 让输入框不能输入 数字
监听keypress事件.判断如果是数字的话阻止浏览器冒泡 <input type="text" id="test"> <script typ ...
- &class::data_member与&object.data_menber之间的差异
前者取data_member在class中的offset:指针类型是:type class::* 后者将会得到该data_member在内存中的真正地址:指针类型是:type*
- Android-AndroidStudio Run 'app'安装APK到设备的过程
1.AndroidStudio 点击Run ‘app’. 2.点击Run ‘app’就会将所有.class文件用SDK工具集处理成.dex, 用SDK工具集将图片/资源/布局文件/AndroidMan ...
- Spring学习(一)——环境准备
以前做的项目都是用.net开发的,以后准备迁移到java平台上,近期正好有个新项目要上马,所以调研下java相关技术.Spring作为java平台下的一个全栈框架, 其简洁优雅的设计和 ...
- AI_图像识别
http://ai.baidu.com/forum/topic/show/595938 经测试识别率相当高,车辆信息识别 文中的import cv2不是python3自带库,需要安装pip3 inst ...
- onbeforeunload事件
window.onbeforeunload=function(){ return "您正在编辑的博客尚未保存,确定要离开此页吗?"; }; 1.这个事件存在的意义就是防止用户不小心 ...
- 数独·唯一性技巧(Uniqueness)-2
Hidden Rectangle(隐藏矩形) 在由候选数(AB)组成.可能形成UR结构的4格中,有2-3格存在额外的候选数,此时若以不存在额外候选数的一格为起点,检查其对角格所在的行和列,若该行和列其 ...
- WinForm使用Label控件模拟分割线(竖向)
用Label控件进行模拟 宽度设为1:this.lblPagerSpliter1.Size = new System.Drawing.Size(1, 21); 去掉边框:this.lblPagerSp ...