jquery事件绑定有三类,分别如下:

.bind()、live()、delegate()

     三者之间没有的区别不是很明显,但是理解它们的具体使用场景,有助于我们写出简洁的代码,并防止我们的交互程序出现没有预料的bug。

事件绑定首先先看来dom树结构

下面提供一个示例图:


jquery attr绑定 jquery绑定click_jquery attr绑定


事件冒泡(也称作事件传递)(Event bubbling aka event propagation)

点击一个链接,触发绑定在链接元素上的click事件,进而触发绑定到这个元素的click事件的函数。

代码如下:


$('a').bind("click", function(){ 

       alert("That tickles!"); 


   });


所以一次点击会触发一个alert。




jquery attr绑定 jquery绑定click_js_02



然后,这个click事件会从DOM树向上传递,传播到父元素,然后传递给每一个祖先元素。


jquery attr绑定 jquery绑定click_js_03



在DOM树中,document是根节点。现在我们能容易的解释
.bind(),.live(),和.delegate()之间的差别


bind()用法


$("a").bind("click", function(){ 
 
        alert("That tickles!"); 
 
   });


这是最直接的绑定方法。jQuery扫描文档找到所有$("a")元素,然后给每个找到的元素click事件绑定处理函数。


live()用法

$("a").live("click", function(){ 
 
        alert("That tickles!"); 

   });


jQuery绑定处理函数到$(document)元素,并把"click"和"a"作为函数的参数。有事件冒泡到document节点的时候,检查这个事件是不是click事件,target element能不能匹配'a' css选择器,如果两个条件都是true,处理函数执行。


live方法也可以绑定到指定的元素(或者说“上下文(context)”)而不用绑定到document,比如:

$("a", $("#container")[0]).live(...);


delegate()用法


$("#container").delegate("a", "click", function(){ 

        alert("That tickles!"); 

   });


jQuery扫描文档找到$("#container"),绑定处理函数到他的click事件,'a' css选择器作为函数的参数。当有事件冒泡到$("#container"),检查事件是不是click,并检查target element是不是匹配css选择器,如果两者都符合,执行函数。


这个和live()方法很相似,除了把事件绑定到特定元素与跟元素的区别。精明的JS'er或许会总结成$("a").live() == $(document),不全是。


为什么.delegate()比 .live()好

jQuery的delegate方法比live方法更应该成为首选有一个原因。考虑以下的场景:

$("a").live("click", function() {
     blah();
});
//or
$(document).delegate("a", "click", function(){
     blah();
});


速度方面


上面第二个执行比第一个快,因为第一个会遍历整个文档查找$("a")元素,并保存为jQuery对象,但是live方法只需要传一个字符串'a‘而已,$()方法并知道我们会用链式表达式在后面用.live()。

delegate方法就只需要找到并存贮$(document)元素就够了。

有一种hack是在$(document).ready()之外调用live方法,这样就会立即执行。这时候DOM还没有填充,也就不会查找元素或创建jQuery对象。

灵活性和链式语法

这方面live方法依然令人费解。想一下,它链在$("a")对象,但实际上是在$(document)对象起作用。因为这个原因,在链式表达式中使用live让人很不安,我觉得live方法变成一个全局的jQeruy方法。$.live("a", ...)会更有意义。

只支持CSS选择器

最后,live方法有一个最大缺点,只能用css选择器,用起来很不方便。

为什么使用.live()或.delegate()而不用.bind()

最后,bind方法看起来更清晰,更直接,是吗?但是这里有两个原因我们推荐delegate或live:

1、绑定事件处理函数到还不存在DOM中的元素。bind方法直接绑定函数到每个单独的元素。不能绑定到还没有添加到页面里的元素,如果你写了$("a").bind(...),然后用ajax给页面增加了新的链接,新添加的链接不会绑定事件。live或delegate或者其它绑定到祖先元素的事件,让现在有的元素,或者以后增的元素都可以使用。

2、绑定处理函数到一个元素或者少数几个元素,监听后代元素,而不是绑定100个相同的处理函数到单独的元素。这样更有性能优势。

阻止冒泡

最后注意一下事件冒泡。通常我们能用这样的方法阻止其它处理函数:

$("a").bind("click", function(e){
     e.preventDefault();
      //or
     e.stopPropagation();
});

但是在这里,用live或delegate方法绑定的事件会一直传递到事件真正绑定的地方才会执行。这时其它的函数已经执行过了。