【jQuery源码】事件存储结构
a. jQuery事件原型——Dean Edwards的跨浏览器AddEvent()设计
源码解读
重新梳理一下数据结构,使用一个例子

<input type="text" id="chua" onClick="f0();"> function f0(){...}
function f1(){...}
function f2(){...}
function f3(){...}
var dom = document.getElementById("chua"); addEvent(dom,"click",f1);
addEvent(dom,"change",f1);
addEvent(dom,"change",f2);
addEvent(dom,"click",f3);
addEvent(dom,"change",f3);

经过addEvent()函数之后,当前的数据结构为:

element: {
onclick: handleEvent(event), //click事件的主监听函数
onchage: handleEvent(event), //change事件的主监听函数
events: {
click:{//这是一个类数组
0: f0, //element已有的事件
1: f1, //下标1实际上就是f1.$$guid
3: f3 //下标3实际上就是f3.$$guid,需要注意的是每一个响应事件都有一个唯一的$$guid作为下标
...
},
change:{//这是一个类数组
1: f1,
2: f2,
3: f3
}
}
}

事件系统会根据调用addEvent的顺序给每个响应函数(也就是addEvent(element, type, handler)中的第三个参数handler)打上标记$$guid。源码
//保证每个不同的事件响应函数只有唯一一个id
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
最终三个响应函数的$$guid标记分别是
f1.$$guid = 1
f2.$$guid = 2
f3.$$guid = 3
而根据源码中
handlers[handler.$$guid] = handler;
那么某一个函数在任何事件响应函数集合中的下标位置是固定的。比如click和change事件都调用f3作为响应事件,那么f3在element.events.click以及element.events.change中的下标位置都是f3.$$guid = 3;即element.events.click[3] = element.events.change[3] = f3。
这个时候假设又新添了一个事件绑定:addEvent(dom,"focus",f3);那么element.events.focus[3] = f3;这也是对象相比于数组的方便之处,数组不可能没有下标0,1,2就直接有3了,但是对象却可以,此时3是作为对象的一个属性名称。
这样的设计,其实已经具备了jquery事件系统的雏形,包含了几个最主要的特点:
1)element上的所有事件,将保存到element.events属性中,不是直接绑定到element上;这样一个事件可以有无数个响应函数。
2)handleEvent作为element所有事件的“主监听函数”,有它统一管理element上的所有函数。
3)所有浏览器都支持element["on" + type]事件绑定方式,跨浏览器兼容。
好啦,明白了addEvent的事件结构,这个想法确实让人觉得眼前一亮。下面分析jQuery的事件结构
b. jQuery的事件结构
所有的函数添加事件都会进入jQuery.event.add函数。该函数有两个主要功能:添加事件、附加很多事件相关信息。我们直接上源码,源码思想和Dean Edwards的跨浏览器兼容事件添加处理类似。
源码分析
依然用实例来说明jQuery的事件结构

<div id="#center"></div> <script>
function dohander(){console.log("dohander")};
function dot(){console.log("dot");} $(document).on("click",'#center',dohander)
.on("click",'#center',dot)
.on("click",dot);
</script>

经过添加处理环节,事件添加到了元素上,而且节点对应的缓存数据也添加了相应的数据。结构如下

elemData = jQuery._data( elem );
elemData = {
events: {
click: {//Array[3]
0: {
data: undefined/{...},
guid: 2, //处理函数的id
handler: function dohander(){…},
namespace: "",
needsContext: false,
origType: "click",
selector: "#center",//选择器,用来区分不同事件源
type: "click"
}
1: {
data: undefined/{...},
guid: 3,
handler: function dot(){…},
namespace: "",
needsContext: false,
origType: "click",
selector: "#center",
type: "click"
}
2: {
data: undefined,
guid: 3,
handler: function dot(){…},
namespace: "",
needsContext: false,
origType: "click",
selector: undefined,
type: "click"
}
delegateCount: 2,//委托事件数量,有selector的才是委托事件
length: 3
}
}
handle: function ( e ) {…}/*事件处理主入口*/{
elem: document//属于handle对象的特征
}
}

jQuery的处理和Dean Edwards的跨浏览器兼容事件添加处理类似,比如为每一个函数添加guid;使用events对象存放响应事件列表,有一个总的事件处理入口handle等。
jQuery做了哪些改进?
1)事件数据不再直接保存在节点上,而是使用jQuery缓存系统内(内部使用的缓存jQuery._data方式存取)
2)事件委托:绑定到当前节点(例子中当前节点是document根节点)的处理函数不仅仅包含当前节点触发事件(click)响应时处理的事件(例子中selector为undefined时对应的处理函数dot);还代理了其他节点(例子中的#center节点)触发事件(click)响应时处理的事件(例子中selector为"#center"对应的处理事件doHandler和dot);委托机制在后续分析。
3)增加了很多功能数据,比如命名空间namespace:这个主要用在自定义事件自定义触发,比如$(document).on("chua.click",'#center',dot),主动触发$("#center").trigger("chua.click")。还有额外数据data:虽然没有看到那个地方有被用到。
【jQuery源码】事件存储结构的更多相关文章
- jquery源码学习(一)——jquery结构概述以及如何合适的暴露全局变量
jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jq ...
- JQuery源码之“对象的结构解析”
吃完午饭,觉得有点发困,想起了以后我们的产品可能要做到各种浏览器的兼容于是乎不得不清醒起来!我们的web项目多数是依赖于Jquery的.据了解,在Jquery的2.0版本以后对IE的低端版本浏览器不再 ...
- jquery源码学习笔记一:总体结构
练武不练功,到老一场空.计算机也一样. 计算机的功,就是原理.如果程序员只会使用各种函数,各种框架,而不知其原理,顶多熟练工人而已.知其然,更要知其所以然. jquery我们用得很爽,但它究竟咋实现的 ...
- jQuery源码逐行分析学习02(第一部分:jQuery的一些变量和函数)
第一次尝试使用Office Word,方便程度大大超过网页在线编辑,不过初次使用,一些内容不甚熟悉,望各位大神见谅~ 在上次的文章中,把整个jQuery的结构进行了梳理,得到了整个jQuery的简化结 ...
- jQuery源码浅析2–奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- jquery源码分析(二)——架构设计
要学习一个库首先的理清它整体架构: 1.jQuery源码大致架构如下:(基于 jQuery 1.11 版本,共计8829行源码)(21,94) 定义了一些变量和函数jQu ...
- 【菜鸟学习jquery源码】数据缓存与data()
前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...
- jQuery源码笔记(一):jQuery的整体结构
jQuery 是一个非常优秀的 JS 库,与 Prototype,YUI,Mootools 等众多的 Js 类库相比,它剑走偏锋,从 web 开发的实用角度出发,抛除了其它 Lib 中一些中看但不实用 ...
- Jquery源码分析与简单模拟实现
前言 最近学习了一下jQuery源码,顺便总结一下,版本:v2.0.3 主要是通过简单模拟实现jQuery的封装/调用.选择器.类级别扩展等.加深对js/Jquery的理解. 正文 先来说问题: 1. ...
- jquery源码解读
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐进增强)优雅的处理能 ...
随机推荐
- 201709021工作日记--Volley源码解读(四)
接着volley源码(三)继续,本来是准备写在(三)后面的,但是博客园太垃圾了,写了半天居然没保存上,要不是公司这个博客还没被限制登陆,鬼才用这个...真是垃圾 继续解读RequestQueue的源码 ...
- 201709015工作日记--IntentService使用
一.IntentService与Service的区别 Service 是 Android 四大组件之一,正常来说,我们直接使用 Service 就可以了. 但是 Service 存在几个问题: 默认不 ...
- Ubuntu在命令行开启远程桌面
在终端执行下列三个命令即可 gsettings set org.gnome.Vino enabled truegsettings set org.gnome.Vino prompt-enabled f ...
- 20155320 2016-2017-2 《Java程序设计》第五周学习总结
20155320 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 错误处理 java中所有错误都会被打包为对象,可以通过try catch 代表错误的对象后做 ...
- 团队博客-第三周:需求改进&系统设计(科利尔拉弗队)
针对课堂讨论环节老师和其他组的问题及建议,对修改选题及需求进行修改 需求规格说明书: 1.打开网页,弹出询问时候创建账号.是:分配数字组成账号,用户填写密码,确定登录进入首页:否,用已有账号登录(传参 ...
- [Linux-vi] The simple set of vi command
Source : https://www.cs.colostate.edu/helpdocs/vi.html What is vi? The default editor that comes wit ...
- Trystrtofloat
TryStrToFloat为 ‘+1’和‘-1’和 ‘.1’是可以装换成功的
- Type conversions in C++类型转换
###Implicit conversions隐式转换* 可以在基本类型之间自由转换:* 可以把任何类型的pointer转换为void pointer:* 可以将子类pointer转换为基类point ...
- EnyimMemcached中用DateTime参数设置过期后赋值有问题的解决.
环境: win10 64位.memcached 1.4.4 64位.EnyimMemcached 2.16.0(ps:2.13.0也有此问题,别的版本就没试了). EnyimMemcached git ...
- JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM ...