上周听邱大师的javaScript讲座时,听邱大师讲到,在jQuery中的绑定事件的几种方法中。.live方法已经逐步被淘汰了。一种应用广泛的方法是on方法,听完讲座之找了些资料看了,对这三种绑定事件的方法有了些许了解。
首先是事件响应过程。
在DOM结构中,任何一个元素在接受到动作如“click”之后,会逐级向上寻找对应的处理诸如“click”事件的方法。当然最快的方法就是在这个元素这一层面就有处理这一事件的方法,根本不需要在父元素层面来处理(bind)。
因此在一个click事件的处理过程中,有这么几个基本东西:
探测器,处理器,处理方案。
探测器是事件的入口,处理器是接受事件,处理事件的地方,处理器的输出就是处理方案。
首先在bind方法中,何谓探测器,何谓处理器,何谓处理方案呢?
比如代码为:
$('a.btn').bind("click",function(){
alert("dont do this!");
});
首先探测器毫无疑问就是$('a.btn')选出来的所有元素了。
其次处理器是什么呢?bind方法中的处理器默认就是探测器this了。
处理方案是:alert(”ba la ba la“);
bind方法简单粗暴,直奔主题。但是问题是,在document ready有的元素并没有产生,而是在javascript中通过一些特定上下文来生成的。那么后面动态生成的元素<a class="btn"></a>是否会有绑定的处理click事件的方法呢?答案是否定的。
另外一种极端情况是live方法,首先,live方法可以完美解决bind针对动态生成元素无法绑定事件的问题。
比如代码为
$(function(){
$('a.btn').bind("click",function(){
alert("dont do this!");
})
$('<a></a>').addClass("btn").appendTo($('div .container'));
})
此时不管在任何时候产生的包含btn这种class的a标签都有了处理点击事件的处理方案alert("dont do this");
注意是 "任何时候”!
这是因为在live方法中,直接将所谓的处理器设置为document了,也就是说任何探测器(比如a标签)探测到事件发生之后,逐层向上报告事件,直至DOM结构的最顶端document接受到之后,给出处理方案。也就是说在live方法中处理器是document。
使用大量的live方法是不好的,因为事件的处理都是在document中进行的,这就好比,一个10亿人的国家,每个人中午吃什么都得国家元首来确定一样匪夷所思。
一种比较科学的方法是将处理器设置在合理的地方。所谓合理指两重意思:
第一,在执行绑定事件方法的时候,处理器应该存在。
第二,最好不要放在顶端。
与之对应的便是 on方法了,在on方法中包含了清晰的探测器和处理器部分。并且处理器和探测器都是可以自定义的。在jQuery的新版本中,bind,live,delegate方法都是通过on方法来内部实现的。
比如:如下的代码是等价的:
$( "a.btn" ).on( "click", function( e ) {} );
$( "a.btn" ).bind( "click", function( e ) {} );
.on的左端就是所谓的处理器,而在on方法的参数表中,省略了探测器,此时的探测器与处理器就是一个东西了。
如下的代码也是等价的:
$( document ).on( "click", "a.btn", function( e ) {} );
$( "a.btn" ).live( "click", function( e ) {} );
此时,可以看到on方法的处理器(也就是写在.on左边的部分)是document,探测器是$("a.btn"),即class为btn的a标签。
与live方法不同的是,live方法中调用者是探测器,处理器是默认的,等价的on方法中on方法的调用者是处理器,探测器写在调用参数中。
而作为已经很灵活的设置探测器和处理器的绑定方法delegate已经和on方法相差无几,如下的代码也是等价的:
$( "div.container" ).on( "click", "a.btn", function( e ) {} );
$( "div.container" ).delegate( "a.btn", "click", function( e ) {} );