再谈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/

posted @ 2012-06-17 21:25 lengyuhong 阅读(...) 评论(...) 编辑 收藏