vivian blog

jquery事件委托方法

前言

前些天做了个点赞的效果,那时候没有用到事件委托的方法,想来相比起用事件委托方法,性能锐减,所以现在记录一下jquery中不同的事件绑定,触发,解绑的方法以及用途

定义

事件代理是指将事件绑定到父级元素中,然后等待事件通过DOM冒泡到该元素再执行,事件侦听中有事件冒泡和事件捕获两种方法,而jquery中通过事件冒泡方式来实现事件代理,分别有bind(),live(),delegate(),on('click'function)方法来实现事件的绑定

  • 事件冒泡:从发生事件的元素向其祖先元素冒泡
  • 事件捕获:事件在DOM中寻找子元素

现在介绍一下事件绑定有那些方法

最普通的事件绑定click()

1
2
3
$("#div1").click(function() {
console.log("点击后触发");
});

不提供解绑定方法,且要每个元素逐一绑定

可解绑定的on(‘click’,function)

1
2
3
$("#div1").on('click',function() {
console.log("点击后触发");
});

可使用$('#div1').off('click');解除绑定

bind()方法(使用冒泡的形式)

1
2
3
$("#div1").bind('click',function consoleMe() {
console.log("点击后触发");
});

可使用unbind()解除绑定
注意:bind()仅适用于为DOM中已经存在的元素绑定事件处理函数,动态生成的DOM元素,则不起作用
eg:

1
2
3
4
5
$(document).ready(function(){
$('.box').bind('click',function(){
$(this).clone().appendTo('.container');
});
});
1
2
3
<div class="container">
<div class="box">click me</div>
</div>

运行结果,单击第一个链接,会追加元素,但是除了第一个链接,其余都没有被绑定click事件

live()

live()在jquery1.9以后已被丢弃,但现在仍记录一下其用法,live()bind()的最大区别在于live()不仅作用于已经存在的DOM元素,还作用于将来动态生成的元素

1
2
3
4
5
$(document).ready(function(){
$('.box').live('click',function(){
$(this).clone().appendTo('.container');
});
});
1
2
3
<div class="container">
<div class="box">click me</div>
</div>

注意live()使用了事件委托的方法,但是它有所下几个缺点:

  1. $()函数会找到当前页面的所有.box元素并创建jquery对象,但在确认事件明白时却不用这个.box元素的组合,而是使用选择符表达式与event.target或其祖先元素进行比较,所以生成jquery对象会导致不必要的开销
  2. live()默认把事件绑定到$(document)元素,如果DOM嵌套很深,事件冒泡通过大量祖先元素会导致性能缺失
  3. 只有$('.container .box')才能使用live()$('.container').find('.box')不行。
    hack手段,早委托方式,其必须在head元素中进行加载,放在尾部则不管用
1
2
3
(function($){
$("#info_table td").live("click",function(){/显示更多信息/});
})(jQuery);//jQuery对象

delegate()

1
2
3
4
$('.container').delegate('.box','click',function(){
$(this).clone().appendTo('.container:first');//若没有涉及到数值的改变,则可以这般写,否则的话,其便会共用一个作用域,
//解决方法有两个,一个是创建闭包,另一个是通过绑定一个Id选择器来获取该元素,并进行事件委托
});

delegate()使用了事件委托的方法,其根元素是具体绑定的元素,由此看来,使用delegate()要比live()效率更高。

提示:使用事件委托时,如果注册到目标元素上的其他事件处理程序使用.stopPropagation()阻止了事件传播,那么事件委托就会失效

on(‘click’,’.box’,function)是比较新的方法

1
2
3
4
$('.container').on('click','.box',function(){
$(this).clone().appendTo('.container:first');//若没有涉及到数值的改变,则可以这般写,否则的话,其便会共用一个作用域,
//解决方法有两个,一个是创建闭包,另一个是通过绑定一个Id选择器来获取该元素,并进行事件委托
});