对jQuery的事件绑定的一些思考

时间:2024-01-18 08:09:26

jQuery的事件绑定

问题

首先我们看下面的一个非经常见的事件绑定代码:

//example
$('#dom').click(function(e){
//do something
}); $('#dom2').click(function(e){
//do something
});

这段代码在事件绑定处理上有一些缺陷:

过多的事件绑定会损耗内存

后期生成HTML会没有事件绑定。须要又一次绑定

语法过于繁杂

解决方式

对于1、2两点的解决方式,我们首先先了解一下jQuery的事件绑定

jQuery的事件绑定有多个方法能够调用。以click事件来举例:

click方法

bind方法

delegate方法

on方法

无论你用的是(click / bind / delegate)之中那个方法,终于都是jQuery底层都是调用on方法来完毕终于的事件绑定。

因此从某种角度来讲除了在书写的方便程度及习惯上挑选。不如直接都採用on方法来的痛快和直接。

关于对方法的详解和用例。请直接訪问jQuery官网。在这里不一一说明。

性能

首先我们须要先对不同的事件绑定方式之间的内存占用差距有一个清晰的认识。

对于性能的分析将採用Chrome的Developer Tools。

Profiles –> Take Heap Snapshot,用这个工具我们能够看到Javascript所占用的内存,能够对性能问题进行分析。

DEMO HTML

<html>
<head>
<script type="text/javascript">
$(function(){
$('#btn-add').click(function(){
$('.ul').prepend('<li><a href="javascript:;">text</a></li>');
});
});
</script>
</head>
<body>
<button id="btn-add">Create Element</button>
<ul class="ul">
<li><a href="javascript:;">text</a></li>
<!-- 2000 line... -->
<li><a href="javascript:;">text</a></li>
</ul>
</body>
</html>

Method 1

$(function(){
$('.ul a').click(function(e){
alert('click event');
});
});

下面是Method 1的内存分析图

内存占用约3.4M

Method 2

$(function(){
$('.ul').on('click', 'a', function(e){
alert('click event');
});
});

下面是Method 2的内存分析图

内存占用约2.0M

结论

Method 1 明显比 Method 2 多耗1.4M的内存

Method 1 无法将事件绑定到通过点击button所新增DOM中来。而Method 2能够。

仅仅要on的delegate对象是HTML页面原有的元素。因为是事件的触发是通过Javascript的事件冒泡机制来监測,所以对于全部子元素(包含后期通过JS生成的元素)全部的事件监測均能有效。且因为不用对多个元素进行事件绑定(在这个example中为2000+a标签),能够有效的节省内存的损耗。

思考

代码如诗。但非常easy变成代码如屎。怎样提高代码的优雅程度也是一个非常有意思的事情。

下面是一个非常普通且普遍的JS文件的代码片段(用于一般站点)

$('#btn-add').click(function(){
//do something
});
$('.action-box #btn-delete').click(function(){
//do something
});
$('.action-box #btn-sort').mouseenter(function(){
//do something
});

毫不夸张的说,当一个js文件上百行后,相似于上面的代码,你非常难从里面发现规律。

可能A喜欢写#btn-add。而B喜欢写.action-box #btn-add来作为选择符。

堆砌着很多不同类型事件。没有一个次序可言

没有运用到我们刚刚所讲的利用事件冒泡来做事件绑定

改进

我们来一步步改进一下之前的JS代码

Version 1

$('.action-box').on('click', '#btn-add', function(){
//do something
});
$('.action-box').on('click', '#btn-delete', function(){
//do something
});

尽管运用了事件冒泡。只是感觉还是有点累赘。.action-box出现多次。感觉不舒服,让我们继续改进

Version 2

$('.action-box').on('click', '#btn-add, #btn-delete', function(){
if($(this).attr('id') == 'btn-add'){
//do something
} else{
//do something
}
});

感觉比刚刚好多了,只是还是须要推断元素来做出对应的处理。能接受。但不完美。

灵感

首先看一下css的增强版本号sass对于css语法上面的改进

/*bed css code*/
.action-box { width: 100%; color: #000; }
#btn-add { color: blue; }
#btn-delete { color: red; } /*good css code*/
.action-box { width: 100%; color: #000; }
.action-box #btn-add { color: blue; }
.action-box #btn-delete { color: red; } /*sass code*/
.action-box {
width: 100%;
color: #000;
#btn-add {
color: blue;
}
#btn-delete {
color: red;
}
}

复制代码

我们能够在 good css code 和 sass code 从中能够能够非常清晰了然的看到文档结构:.action-box 下面有两个button。

这能否让sass这样的代码结构运用到js中来呢?答案当然是能够。

$('.action-box').coffee({
click: {
'#btn-add': function(){
//do something
},
//这是是支持jQuery的':last / [attr] / :eq(0)'等方法的
'#btn-delete': function(){
//do something
}
},
mouseenter: {
'#btn-sort': function(){
//do something
}
}
});

喜欢这样的结构吗?

清晰明了的文档结构

运用事件冒泡,有效降低内存的占用

第一级别用事件名称来划分

第二级别的属性名相当于选择符。

coffee函数的源代码

$.fn.coffee = function(obj){
for(var eName in obj)
for(var selector in obj[eName])
$(this).on(eName, selector, obj[eName][selector]);
}

聊聊数行代码。就能够做成一个非常美妙的语法糖

Enjoy yourself ! ^_^

假设你认为这篇文章还不错,请帮忙点击一下推荐,谢谢!