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


Posted in Javascript onApril 20, 2013

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

//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所占用的内存,能够对性能问题进行分析。

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

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

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

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

以下是Method 2的内存分析图

内存占用约2.0M

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

结论
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、没有运用到我们刚刚所讲的利用事件冒泡来做事件绑定

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

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

Javascript 相关文章推荐
html5+javascript制作简易画板附图
Apr 25 Javascript
简单的js图片轮换代码(js图片轮播)
May 06 Javascript
jQuery实现鼠标划过修改样式的方法
Apr 14 Javascript
Bootstrap的图片轮播示例代码
Aug 31 Javascript
jQuery简单注册和禁用全局事件的方法
Jul 25 Javascript
jQuery插入节点和移动节点用法示例(insertAfter、insertBefore方法)
Sep 08 Javascript
jquery中用函数来设置css样式
Dec 22 Javascript
Bootstrap 表单验证formValidation 实现表单动态验证功能
May 17 Javascript
angularjs+bootstrap实现自定义分页的实例代码
Jun 19 Javascript
利用 spin.js 生成等待效果(js 等待效果)
Jun 25 Javascript
jQuery绑定事件方法及区别(bind,click,on,live,one)
Aug 14 jQuery
在layui中layer弹出层点击事件无效的解决方法
Sep 05 Javascript
A标签中通过href和onclick传递的this对象实现思路
Apr 19 #Javascript
javascript中onclick(this)用法介绍
Apr 19 #Javascript
jQuery使用一个按钮控制图片的伸缩实现思路
Apr 19 #Javascript
使用jQuery同时控制四张图片的伸缩实现代码
Apr 19 #Javascript
使用jQuery实现的网页版的个人简历(可换肤)
Apr 19 #Javascript
兼容IE和Firefox火狐的上下、左右循环无间断滚动JS代码
Apr 19 #Javascript
JS实现div内部的文字或图片自动循环滚动代码
Apr 19 #Javascript
You might like
CI框架AR操作(数组形式)实现插入多条sql数据的方法
2016/05/18 PHP
在javascript中如何得到中英文混合字符串的长度
2014/01/17 Javascript
JS获取时间的方法
2015/01/21 Javascript
jQuery选择器之基本选择器与层次选择器
2015/03/03 Javascript
jquery预加载图片的方法
2015/05/27 Javascript
jQuery自动添加表单项的方法
2015/07/13 Javascript
javascript手风琴下拉菜单实现代码
2015/11/12 Javascript
jQuery插件passwordStrength密码强度指标详解
2016/06/24 Javascript
基于Bootstrap实现下拉菜单项和表单导航条(两个菜单项,一个下拉菜单和登录表单导航条)
2016/07/22 Javascript
jQuery之动画效果大全
2016/11/09 Javascript
Bootstrap表单制作代码
2017/03/17 Javascript
AngularJS入门教程一:路由用法初探
2017/05/27 Javascript
JavaScript贪吃蛇小组件实例代码
2017/08/20 Javascript
微信小程序实现图片上传放大预览删除代码
2020/06/28 Javascript
微信小程序开发(一):服务器获取数据列表渲染操作示例
2020/06/01 Javascript
微信小程序实现首页弹出广告
2020/12/03 Javascript
解决pycharm界面不能显示中文的问题
2018/05/23 Python
python实现嵌套列表平铺的两种方法
2018/11/08 Python
Python3.5 处理文本txt,删除不需要的行方法
2018/12/10 Python
Python设计模式之简单工厂模式实例详解
2019/01/22 Python
Python骚操作之动态定义函数
2019/03/26 Python
Python使用Pickle模块进行数据保存和读取的讲解
2019/04/09 Python
python实现两个文件夹的同步
2019/08/29 Python
浅谈python中统计计数的几种方法和Counter详解
2019/11/07 Python
简单了解Python write writelines区别
2020/02/27 Python
Python 将 QQ 好友头像生成祝福语的实现代码
2020/05/03 Python
python如何处理程序无法打开
2020/06/16 Python
基于python的opencv图像处理实现对斑马线的检测示例
2020/11/29 Python
selenium+python自动化78-autoit参数化与批量上传功能的实现
2021/03/04 Python
美国在线鞋类零售商:LifeStride
2019/06/09 全球购物
Ariat英国官网:为世界顶级马术运动员制造最优质的鞋类和服装
2020/02/14 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
平安校园建设方案
2014/05/02 职场文书
党支部综合考察材料
2014/05/19 职场文书
网络舆情信息简报
2015/07/21 职场文书
干货:如何写好工作总结报告!
2019/05/10 职场文书