在jQuery类库中,事件绑定与事件委托的用法受到了广泛的关注。不仅如此,这还成了当今前端攻城狮的
热门面试题目。十次面试有七八次会问到这个问题,因此,了解掌握事件的绑定和委托,还是比较重要的。
冒泡
众所周知,HTML的DOM结构自外而内,层层包裹。如:DIV>P>SPAN>A,这样式的,当我们的事件定义
到最里面的a标签上时,由于冒泡的特定,如果在外层如div,p,span上也定义了相同事件的话,a标签上的事件执行时,外层事件也会同样被执行。而当外层定义了事件,触发a标签时,外层事件同样也会被执行,这就是冒泡的特性,事件总会沿着从里到外执行。
事件绑定
事件绑定,即为一个标签绑定相应的事件,当这个事件触发时,就会执行事件中的方法。我们会为每一个元素绑定一个事件。
事件委托
在事件绑定中,我们可以为每一个元素绑定一次事件。但目前来看,HTML页面之复杂,页面中可能会存在成百上千个元素,如果我们为每一个元素绑定事件的话,势必影响性能。不仅如此,还有很多元素是动态生成的,我们如果用事件绑定的话,这些动态生成的元素将不会有相应的事件绑定,因为一个缺点:事件绑定只能给所有存在的元素上绑定事件。我们可以看到一个特性:如果在外层元素上绑定事件,那么即使事件发生在此元素内部子元素上,也会通过冒泡使外层元素的事件执行。那么,如果我们本意是给子元素绑定事件,但是由于子元素太多又或者子元素是动态加载,为了性能不能直接绑定的话,我们将事件定义到外层元素上,子元素只需要触发事件,通过冒泡,自然而然的触发外层元素事件执行,这样就可以解决事件绑定的缺点问题。这个,就是我们所说的事件委托。
bind()方法
在jQuery中我们有一个bind()方法,从字面意思可以看出,他是给元素绑定事件的,
$("table td").bind("click",function(){/*这里是代码*/});
bind()方法用起来简单方便,但是非常的消耗性能,如果需要找到指定的td元素,则需要遍历,当td数量相当庞大时,性能消耗非常大。不仅如此,如果td元素是动态加载的话,bind()方法是不能绑定到这些动态加载的元素上的。
live()方法
live()方法在最新的jQuery版本中已经被废弃,因为他缺点多,但我们在这里还要说一说这个live()方法。
$("table td").live("click",function(){/*这里是代码*/})
其用法与绑定基本相同,但是有很多缺点:
1 尽管他是要在
("tabletd")某一个table下检索td元素来绑定事件,但是他还是会将事件绑定到
(document)对象,这样,如果DOM结构层次够多够深的话,不仅性能慢,而且还会造成不必要的后果。
2 不仅如此,事件被绑定到$(document)上之后,live()事件会检索所有的td元素,并对其进行事件绑定,这与我们的初衷是不一样的。
3 live()事件不能在代码链后使用:
$(".class td").live("click",function(){/*这里是代码*/}); //这样写正确
$(".class").find("td").live("click",function(){/*这里是代码*/}); //这样写不行
使用live()方法势必会产生很多jQuery()对象,为了避免这个发生,我们需要在$(document).ready(function(){});之外执行,也是为了避免污染明明控件,我们选择用一个自己执行函数来执行这句代码:
(function($){
$(".class td").live("click",function(){/*这里是代码*/});
})(jQuery);
更严重的是,这句话,必须要放在header 引用或header里执行才起到作用。
为了避免live()方法绑定到$(document)上,我们可以给他的jQuery对象传一个参数:
$(".class td",$(".someDiv")).live("click",function(){/*这里是代码*/})
这样,会在$(“.someDiv”)下遍历找到相应的元素再进行方法的绑定。
delegate()方法
live()方法使用麻烦,还有一定的局限性,因此jQuery最新版本已经废弃了它。delegate()方法可以解决bind()方法和live()方法中遇到的所有的问题:
$(".class").delegate("td","click",function(){/*这里是代码*/});
delegate()方法简洁明了,可以很快将委托方,事件,函数,及受委托方绑定在一起。
在.class元素上绑定一个click方法,如果.class元素中的某一个td发生了click事件,那么这个方法就会被执行。不仅如此,动态加载的td元素也可以触发该方法了。
on()方法
从jQuery源码可以看到,bind(),delagate()方法都是有on()方法生成的。因此目前普遍使用on()方法进行事件绑定和事件委托:
$(".class td").on("click",function(){/*这里是代码*/});
$(".class").on("click","td",function(){/*这里是代码*/});
on()方法中,如果event事件后没有selector得话,那就是普通的事件绑定,就是给jQuery对象绑定一个click方法。如果event事件后有selector的话,那么就是时间委托了。jQuery对象就是受委托方,seletor就是委托方,给jQuery对象绑定事件,如果触发时间的是委托方,那么事件就会被执行。
总结来说,目前使用on()方法既可以实现事件绑定,也可以实现事件委托,是比较好用的方法。其他几个方法应用的比较少,限制又多。因此on()方法用来解决事件委托与绑定的问题还是比较热门的。