再谈jQuery中.live()和.delegate()之间的区别
之前看了这篇文章《The Difference Between jQuery’s .bind(), .live(), and .delegate()》一文,觉得自己已经完全理解了.live() 和.delagate(),直到遇到了一个另一个问题,发现还是有遗漏。
先再补充下知识,简单讲讲两者之间的区别:
.live()
$('a').live('click', function() { alert("That tickles!") });
JQuery把alert函数绑定到$(document)元素上,并使用’click’和’a’作为参数。任何时候只要有事件冒泡到document节点上,它就查看该事件是否是一个click事件,以及该事件的目标元素与’a’这一CSS选择器是否匹配,如果都是的话,则执行函数。
live方法还可以被绑定到具体的元素(或context)而不是document上,像这样:
$('a', $('#container')[0]).live(...);
.delegate()
$('#container').delegate('a', 'click', function() { alert("That tickles!") });
jQuery扫描文档查找$(‘#container’),并使用click事件和’a’这一CSS选择器作为参数把alert函数绑定到$(‘#container’)上。任何时候只要有事件冒泡到$(‘#container’)上,它就查看该事件是否是click事件,以及该事件的目标元素是否与CCS选择器相匹配。如果两种检查的结果都为真的话,它就执行函数。
可以注意到,这一过程与.live()类似,但是其把处理程序绑定到具体的元素而非document这一根上。精明的JS’er们可能会做出这样的结论,即$('a').live() == $(document).delegate('a'),是这样吗?嗯,不,不完全是。
为什么.delegate()要比.live()好用
基于几个原因,人们通常更愿意选用jQuery的delegate方法而不是live方法。考虑下面的例子:
$('a').live('click', function() { blah() }); // 或者 $(document).delegate('a', 'click', function() { blah() });
速度
后者实际上要快过前者,因为前者首先要扫描整个的文档查找所有的$(‘a’)元素,把它们存成jQuery对象。尽管live函数仅需要把’a’作为串参数传递以用做之后的判断,但是$()函数并未知道被链接的方法将会是.live().
而另一方面,delegate方法仅需要查找并存储$(document)元素。
一种寻求避开这一问题的方法是调用在$(document).ready()之外绑定的live,这样它就会立即执行。在这种方式下,其会在DOM获得填充之前运行,因此就不会查找元素或是创建jQuery对象了。
灵活性和链能力
live函数也挺令人费解的。想想看,它被链到$(‘a’)对象集上,但其实际上是在$(document)对象上发生作用。由于这个原因,它能够试图以一种吓死人的方式来把方法链到自身上。实际上,我想说的是,以$.live(‘a’,…)这一形式作为一种全局性的jQuery方法,live方法会更具意义一些。
仅支持CSS选择器
最后一点,live方法有一个非常大的缺点,那就是它仅能针对直接的CSS选择器做操作,这使得它变得非常的不灵活。
欲了解更多关于CSS选择器的缺点,请参阅《Exploring jQuery .live() and .die()》一文。
以上是我在网上找到的介绍.live()和.delegate()区别的资料,相信大家对此应该有了大致的了解,那我们再来看下以下的应用场景:
<!DOCTYPE> <html> <head> <script src="http://code.jquery.com/jquery-latest.js"></script> </head> <body> <div> <span class="cb"> <a href="./xxxxxx">相关链接</a> </span> </div> <script type="text/javascript"> $('.ca a').live("click", function (event) { location.href = 'ca.html'; return false; }); $('div').delegate(".cb a", "click", function (event) { location.href = 'cb.html'; return false; }); </script> </body> </html>
以上代码是在一个连接中绑定了两个事件,跳转到不同的页面。(真正项目中,这种例子明显是个bug,不过在多人同时开发一个项目时,这种情况还是可能出现,每个开发者都根据id或者class来绑定事件,在不小心时会出现重叠)。ok,那大家觉得这种应用场景,当用户点击了那个连接时,是会跳转到ca.html?还是cb.html,也就是先触发live事件,还是delegate事件?
好,揭晓答案:是delegate事件,因为delegate是绑定在div上,而live是绑定在document上。当事件冒泡时,因此会先触发delegate事件。
参考文章:
http://kb.cnblogs.com/page/94469/
http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/