对jQuery的事件绑定的一些思考
来源:互联网 发布:知乎回复越来越长 编辑:程序博客网 时间:2024/04/28 05:09
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官网,在这里不一一说明。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文件上百行后,类似于上面的代码,你很难从里面发现规律。
- 可能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]);}
聊聊数行代码,就可以做成一个很美妙的语法糖
- 对jQuery的事件绑定的一些思考
- 对jQuery的事件绑定的一些思考
- 对jQuery的事件绑定的一些思考
- 对jQuery的事件绑定的一些思考
- 对jQuery的事件绑定的一些思考
- Jquery绑定事件的一些思考和总结
- 对“绑定”的思考
- 对js事件绑定的一些理解
- 用Jquery 的一些收获 事件删除 重复绑定事件
- jQuery的绑定事件
- jQuery的事件绑定
- jquery的绑定事件
- jquery的事件绑定
- JQuery事件的绑定
- jQuery的事件绑定
- jquery对一些事件的递增
- Jquery对动态生成的元素绑定事件
- Jquery对动态生成的元素绑定事件
- YouTube架构学习体会
- 有向图的DFS遍历及判断是否有环(算法导论)
- UVA 题目409 - Excuses, Excuses!
- 基础复习
- WINCE下创建多个文件分区
- 对jQuery的事件绑定的一些思考
- 网页内容爬取:如何提取正文内容
- 回顾MySpace架构的坎坷之路
- wince 下USB 虚拟多个串口问题
- iOS网络编程-ASIHTTPRequest异步请求
- 随机梯度下降(Stochastic Gradient Descend, SGD)算法在大规模数据机器学习问题的使用
- WinCE中将调试信息写入文件的方法
- 爱上多线程——重复初始化问题
- 对 nginx 图片反盗链的几种常见情况的综合分析