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)) 其中,参 ...
随机推荐
- 学习tomcat(一)----用IDEA调试tomcat源码
一直在使用tomcat,但却不怎么熟悉tomcat的"运作流程",今天就 参照参考文章进行了代码搭建(代码的github在文末),并修改了一些操作.学习下tomcat的" ...
- 深入理解java虚拟机(十四)正确利用 JVM 的方法内联
在IntelliJ IDEA里面Ctrl+Alt+M用来拆分方法.选中一段代码,敲下这个组合,非常简单.Eclipse也用类似的快捷键,使用 Alt+Shift+M.我讨厌长的方法,提起这个下面这个方 ...
- logback-spring.xml配置文件详解
logback-spring.xml配置文件 自己改下value="G:/logs/pmp"这个值,如果你相关依赖弄好的话,直接复制粘贴即用 输出的日志文件的名称最好也改下,下文中 ...
- 【C#】事件
前言:CLR事件模式建立在委托的基础上,委托说调用回调方法的一种类型安全的方式. 我个人觉得事件本质就是委托,所以把委托弄清楚,只要知道事件基本语法就会使用了(如果说到线程安全,我个人觉得这个应该和线 ...
- [LeetCode 题解]: ZigZag Conversion
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 The string ...
- [javascript]模块化&命名污染—from 编程精解
最近看了编程精解里面的模块化一章,很受启发. /****************/ 在开发的实际过程中,根据页面或者逻辑布局,js代码可以按照功能划分为若干个区块:数据交互.表单验证.页面布局等等模块 ...
- ie8在win7系统下怎么安装或重装?[转载]
(一)对于已卸载了IE8的用户 因为微软并没有提供用于Windows 7系统的IE8独立安装包,Windows 7用户是无法通过下载安装包的方法来重装IE8的,而是默认将IE8的安装程序集成在Wind ...
- Hierarchical Z-Buffer Occlusion Culling
While I was at GDC I had the pleasure of attending the Rendering with Conviction talk by Stephen Hil ...
- fatal: Authentication failed for又不弹出用户名和密码 解决办法
各位,如果能弹出来,一定是你账号密码搞错了,就别继续看了. image.png 切换命令行: image.png 依然报错, 说到这个问题,又可以长篇大论了, 我使用的是tortoisegit ...
- fdisk 磁盘分区
.[root@test4 ~]# fdisk /dev/sda //对sda磁盘进行分区 Device contains neither a valid DOS partition table, no ...