对jQuery的事件绑定的一些思考(补充)

 更新时间:2013年04月20日 23:16:16   作者:  
一般jquery事件绑定会带来过多的事件绑定会损耗内存,后期生成HTML会没有事件绑定,需要重新绑定,语法过于繁杂等问题
首先我们看下面的一个很常见的事件绑定代码:

复制代码 代码如下:

//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官网,在这里不一一说明。api.jquery.com

性能

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

对于性能的分析将采用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标签),能够有效的节省内存的损耗。

思考
代码如诗,但很容易变成代码如屎。如何提高代码的优雅程度也是一个很有意思的事情。

以下是一个很普通且普遍的JS文件的代码片段(用于一般网站)

复制代码 代码如下:

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


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

1、可能A喜欢写#btn-add,而B喜欢写.action-box #btn-add来作为选择符。
2、堆砌着许多不同类型事件,没有一个次序可言
3、没有运用到我们刚刚所讲的利用事件冒泡来做事件绑定

改进
我们来一步步改进一下之前的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
    }
  }
});

喜欢这种结构吗?

1、清晰明了的文档结构
2、运用事件冒泡,有效减少内存的占用
3、第一级别用事件名称来划分
4、第二级别的属性名相当于选择符。

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 !  ^_^

作者: CoffeeDeveloper

相关文章

  • 基于JQuery的Pager分页器实现代码

    基于JQuery的Pager分页器实现代码

    页面分页对于程序员来说最熟悉不过,在WEB开发中经常需要对页面进行分页,jQuery插件JQuery Pager分页器能轻松实现javascript分页功能,只需要几行代码,javascript分页简单搞定。
    2010-07-07
  • jQuery获取URL请求参数的方法

    jQuery获取URL请求参数的方法

    这篇文章主要介绍了jQuery获取URL请求参数的方法,涉及jquery针对URL的获取与字符串的操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • JQuery中操作Css样式的方法

    JQuery中操作Css样式的方法

    本篇文章主要是对JQuery中操作Css样式的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-02-02
  • jquery实现页面图片等比例放大缩小功能

    jquery实现页面图片等比例放大缩小功能

    本文将利用jquery实现页面图片等比例放大和缩小。说明: 页面中经常需要将未知大小的图片展示在有限的空间里, 如果直接指定图片的width和height值, 就有可能造成图片走样, 这段代码就是为解决这个问题设计
    2014-02-02
  • jQuery无刷新上传之uploadify3.1简单使用

    jQuery无刷新上传之uploadify3.1简单使用

    本文主要介绍jQuery插件uploadify3.1的简单使用,希望能帮到大家,有需要的朋友可以参考一下。
    2016-06-06
  • ASP SQL防注入的方法

    ASP SQL防注入的方法

    前一篇我们介绍了一种防SQL注入的终极方法,也就是最原始、最简单、最有效也是最通用的方法,就是数据类型的检查加单引号的处理,具体的内容前面一篇已经介绍过了,这里我就不重复了
    2008-12-12
  • jquery 提交值不为空的元素示例代码

    jquery 提交值不为空的元素示例代码

    表单提交的时候 ,是根据元素的name这个属性来的,只要不加name属性 就不会提交,具体实现如下,感兴趣的朋友可以参考下哈
    2013-05-05
  • jquery 获取dom固定元素 添加样式的简单实例

    jquery 获取dom固定元素 添加样式的简单实例

    本篇文章主要是对jquery获取dom固定元素 添加样式的简单实例进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-02-02
  • jQuery动态生成不规则表格(前后端)

    jQuery动态生成不规则表格(前后端)

    这篇文章主要介绍了jQuery动态生成不规则表格的实现代码,非常不错,具有参考借鉴价值,需要的朋友参考下
    2017-02-02
  • jquery处理json对象

    jquery处理json对象

    JSON(JavaScript Object Notation)javscript对象标记,是一种轻量级的数据交换格式。具体的详细基础知识可以参考JSON官网http:/www.json.org/。不说太多废话,直接说说我对JSON的理解吧。
    2014-11-11

最新评论