发表于: 2017-04-26 17:51:51
2 1196
jquery中的bind(),live(),delegate(),on()有什么区别
1.背景介绍.
很多开发者很困惑关于jQuery中的.bind(), .live(), .delegate() 和 .on() 的使用以及它们的不同。
甚至很多人根本不知道有这些事件。在jq3.0+以上版本,.bind(), .live(), .delegate()已经被废除。新的.on()方法可以实现.bind() .live() 和 .delegate()的功能。但是了解这些方法仍然是有用的,它可以帮助我们理解原理。
2.知识剖析
认识4种方法的使用。
bind()
指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
.live()
jQuery 给所有匹配的元素附加一个事件处理函数,即使这个元素是以后再添加进来的也有效。
delegate()
指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
.on()
在选择元素上绑定一个或多个事件的事件处理函数。
on()方法绑定事件处理程序到当前选定的jQuery对象中的元素。在jQuery 1.7中.on()方法 提供绑定事件处理程序所需的所有功能。帮助从旧的jQuery事件方法转换.bind(), .delegate(), 和 .live().
$( "#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 ) {} );
3.常见问题
它们的实现原理
各自区别与优缺点?
4.解决方案
可视化一个HMTL文档的DOM树.一个简单的HTML页面看起来就像是这个样子:
当我们点击一个链接时,其触发了链接元素的单击事件,该事件则引发任何我们已绑定到该元素的单击事件上的函数的执行。
$('a').bind('click',function(){alert('that tickles!')})
click事件接着会向树的根方向传播,广播到父元素,然后接着是每个祖先元素,只要是它的某个后代元素上的单击事件被触发,事件就会传给它。
在操纵DOM的语境中,document是根节点。
.bind()
$('a').bind('click',function(){alert('That tickles!');})
JQuery扫描文档找出所有的$(‘a')元素,并把alert函数绑定到每个元素的click事件上.
优点:跨浏览器;
非常方便和快捷地绑定事件;
简单的实现方法(.click() .hover() ,etc…)让它用起来很方便;
对于简单的ID选择器来说,使用.bind()不仅方便,而且当触发这个事件的时候能够即时响应。
缺点:
这个方法会附加相同的处理程序到每一个匹配到的元素上;
对于动态添加的属于匹配到的元素,不会被触发事件的;
性能问题,对于处理大量的匹配元素的时候;
如果在页面加载前要处理添加事件的话,会影响加载效率的。
.live()
$('a').live('click',function(){alert('That tickles!')})
JQuery把alert函数绑定到$(document)元素上,并使用'click'和'a'作为参数。任何时候只要有事件冒泡到document节点上,它就查看该事件是否是一个click事件,以及该事件的目标元素与'a'这一CSS选择器是否匹配,如果都是的话,则执行函数.
live方法还可以被绑定到具体的元素(或“context”)而不是document上:
$('a',$('#container')[0]).live('click',function(){alert('That tickles!')});
优点:相对于.bind()的循环注册很多次事件处理程序来说.live()只注册一次事件处理程序;
从.bind()更新到.live()的方法对程序更改很少,只需要替换“bind”为”live”;
对于动态添加的属于匹配到的元素,也能够执行处理程序;
在document元素没有全部加载完之前都能够几乎不花时间地绑定并触发事件。
缺点:
此方法在jQuery1.7的时候已经废除,你应该逐步从你的代码中替换掉该方法;
链接不能够正常的支持这个方法;
这个方法被抛弃是因为它只能够绑定事件处理程序到document上;
event.stopPropagation()不再有效了,因为事件已经委托到了document上;
由于所有的选择器和事件信息都是附加到了document上的,所以一个确定的事件要触发,必须通过大量的存储信息来匹配到;
由于事件都是委托到了document上的,所以如果DOM太深的话,会影响到性能;
.delegate()
$('#container').delegate('a','click',function(){alert('That tickles!')})
JQuery扫描文档查找$('#container'),并使用click事件和'a'这一CSS选择器作为参数把alert函数绑定到$('#container')上。任何时候只要有事件冒泡到$('#container')上,它就查看该事件是否是click事件,以及该事件的目标元素是否与CSS选择器相匹配。如果两种检查的结果都为真的话,它就执行函数。这一过程与.live()类似,但是其把处理程序绑定到具体的元素而非document这一根元素上。
优点:
可以自由选择附加的选择器和事件信息的位置;
链接也可以有效的支持;
jQuery仍然需要循环访问选择器和事件数据来确定匹配,但是因为能够选择这些信息附加的位置,所以通过匹配的量小很多;
由于这种技术使用了事件委托,所以它能很好的动态处理添加到DOM元素;
如果委托事件到了document上,也可以在document全部准备完之前绑定和调用;
缺点:
方法从.bind()更改到.delegate()比较麻烦<br>
如果把选择器和事件数据附加到了document上,仍然需要很多的匹配信息,但是相对于.live()的存储量要小很多了
.on()
下面的代码片段来自jQuery 1.7.1 codebase in GitHub
// ... 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 ...
优点
为各种事件绑定方法带来了统一性<br>
简化了jQuery代码库,并删除一个界别的重定向,因为通过调用这个方法实现了 .bind() .live() 和 .delegate()
仍然提供了好用的.delegate()方法,但是也仍然对.bind()方法提供了支持
缺点:
调用这个方法的各个形式较杂,会带来一些混乱
6.扩展思考。
在.on()全面使用前,为什么选择.live()或.delegate()而不是.bind()
1.为了把处理程序附加到可能还未存在于DOM中的DOM元素之上。因为bind是直接把处理程序绑定到各个元素上,它不能把处理程序绑定到还未存在于页面中的元素之上。
2.如果你运行了$('a').bind(…),而后新的链接经由AJAX加入到了页面中,则你的bind处理程序对于这些新加入的链接来说是无效的。而另一方面live和delegate则是被绑定到另一个祖先节点上,因此其对于任何目前或是将来存在于该祖先元素之内的元素都是有效的。
3.或者为了把处理程序附加到单个元素上或是一小组元素之上,监听后代元素上的事件而不是循环遍历并把同一个函数逐个附加到DOM中的100个元素上。把处理程序附加到一个(或是一小组)祖先元素上而不是直接把处理程序附加到页面中的所有元素上,这种做法带来了性能上的好处。
7.参考文献
参考一:http://www.jb51.net/article/27309.htmjQuery中的.bind()、.live()和.delegate()之间区别分析
参考二:http://blog.csdn.net/hi_kevin/article/details/37757657 详解jQuery中 .bind() vs .live() vs .delegate() vs .on() 的区别
8.更多讨论
收获总结?
使用.bind()方法是很浪费资源的,因为它要匹配选择器中的每一项并且挨个设置相同的事件处理程序。
建议停止使用.live()方法,因为它已经被弃用了,它有很多的问题。
.delegate()方法“很划算”用来处理性能和响应动态添加元素的时候。
新的.on()方法主要是可以实现.bind() .live() 甚至 .delegate()的功能。如果使用了1.7+的jQuery的话,建议使用.on()方法。
评论