jquery 实现原理 六:event

一,基本原理

1.1 数据缓存 data

在事件之前是应该先讲解下data的实现的,因为在event的实现中,需要用到data,用来存储用户在element上注册的事件回调函数,这个data的实现比较简单,所以在这里简单说一下。

$.data可以在一个元素上存储数据,比如$('xxx').data("a", 1)。实现原理很简单,先初始化一个cache对象,然后在元素上添加一个唯一的id属性,这个id对应一个object,然后把这个对应关系存储在cache中。
这样调用data的时候,就可以根据元素上的唯一id去cache中取出一个对象,然后在这个对象上做增删查改的操作即可。
需要注意的一点是,Data函数是在闭包中的,无法直接访问,而jquery帮我们初始化了两个data,分别是data_priv和data_user,即一个是私有的,一个是给用户用的。所以jquery很多模块内部实现会用到data来存储数据,但是你调用data却无法读取到,就是这个原因,jquery内部用的是data_priv来存储的,而用户调用的时候用的是data_user来存储的。

1.2 event的基本实现

还记得dom事件模型吗,0级事件模型和2级事件模型。因为浏览器的实现问题,ie下的二级事件模型只有冒泡而没有捕获过程。而且ie的添加事件的方法名和事件的event对象都和其他浏览器不一样。所以jquery对这个做了一个封装。

event的基本原理也很简单。jquery会调用data方法在element上存储一个events对象和一个handle函数(不要再问我为什么你用data读出来是undefined,参见1.1中的解释data_priv和data_user的解释)。然后把所有的回调函数都存在这个events对象里,events对象的结构如下:
{
     click: queue
     dbclick:queue
     change:queue
     keyup:queue
     …
}
其中handle是一个jquery构造的回调函数,这个函数才是原生事件触发时直接调用的函数,这个函数定义如下:
eventHandle = elemData.handle = function( e ) {
                    // Discard the second event of a jQuery.event.trigger() and
                    // when an event is called after a page has unloaded
                    return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
                         jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
                         undefined;
               };
     
其作用就是调用再次调用用户注册的回调函数。
然后就是每个事件名称都对应一个队列,当你调用jqueryapi注册事件时,你的回调函数会被放到对应的队列中,比如click就会放在click队列中。

举个例子总结下。假设执行代码 $("a").click(b);其中b是一个函数,那么jquery的执行过程是:
1,调用data_priv读取handle函数和events对象
2,存储b到events.click队列中
3,调用原生api把handle注册为回调函数
然后触发事件的时候会通过handle函数来调用b,说白了handle就是一个代理而已。

二,源码结构


2.1 helper 对象 jQuery.event

jQuery.event 是一个helper对象,它是事件机制的真正实现,其他的api比如 on, click什么的都是对他的封装而已。基本结构如下:
jQuery.event = {
     add: function(){}
     remove: function(){}
     trigger: function(){}
     dispatch: function(){}
     handlers: function(){}
     fix: function(){}
     special: function(){}
}
说说每个函数的作用:
add 
在一个元素上注册一个事件,其实现过程在上面已经说过了,具体实现细节就不谈了。
remove
删除一个事件
trigger:触发事件,这里是触发浏览器原生的事件,注意其中有这么一行代码:elem[ type ]();
dispatch:事件分发,注意和trigger的区别,trigger是触发原生事件,而dispatch只是调用jquery注册的事件。如果你调用trigger,其会触发原生事件,然后原生事件会触发handle函数,handle函数会调用dispatch来调用你之前用jquery注册的其他回调函数。
handlers:返回用户注册的回调函数队列
fix:修正event参数
special:处理一些特殊的事件,比如onload focus等等

2.2 jQuery.Event

这是回调函数中的event参数,这里做了标准化的处理,因此所有的浏览器中的event参数都会保持一致的api

2.3 封装api

因为有了 event和Event,下面就是封装了各种接口,最终都是调用event中的对应方法来实现的,后面依次定义了这些接口:on, one, off, trigger。

2.4 别名:

在event.alias中定义了一堆别名,本质只是一个快捷方式而已,比如click其实就是on("click"),hover就是mouseenter和mouseleave
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值