jQuery从入门到精通源码分析系列(十八) : 事件绑定 - 体系结构
沉沙 2018-07-10 来源 : 阅读 1073 评论 0

摘要:本篇jQuery教程通过代码讲解了事件绑定的体系结构,希望阅读本篇文章以后大家有所收获,帮助大家对jQuery的理解更加深入。

那么jQuery事件处理机制能帮我们处理那些问题?

1. 毋容置疑首先要解决浏览器事件兼容问题

2. 可以在一个事件类型上添加多个事件处理函数,可以一次添加多个事件类型的事件处理函数

3. 提供了常用事件的便捷方法

4. 支持自定义事件

5. 扩展了组合事件

6. 提供了统一的事件封装、绑定、执行、销毁机制

7. ……


jQuery的事件绑定有多个方法可以调用,以click事件来举例:

· click方法

· bind方法

· delegate方法

· on方法

$('#foo').click(function(){ })

$('#foo').bind('click',function(){ })

$("foo").delegate("td", "click", function() { });

$("foo").on("click", "td", function() { });

以上四种绑定都能达到同一样的效果,但是各自又有什么区别,内部又是如何实现?

源码分析

click方式

jQuery.each( ("blur focus focusin focusout load resize scroll unload
click
 dblclick " +
        "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
        "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
 
        // Handle event binding
        jQuery.fn[ name ] = function( data, fn ) {
            return arguments.length > 0 ?
                this.on( name, null, data, fn ) :
                this.trigger( name );
        };
    });

源码很简单,合并15种事件统一增加到jQuery.fn上

内部调用this.on / this.trigger

bind方式

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
unbind: function( types, fn ) {
    return this.off( types, null, fn );
},

同样调用的this.on/this.off

delegate方式

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},
undelegate: function( selector, types, fn ) {
    // ( namespace ) or ( selector, types [, fn] )
    return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
}

同样调用的this.on/this.off

one方式

one: function( types, selector, data, fn ) {
    return this.on( types, selector, data, fn, 1 );
},
还是this.on

可见以上的接口只是修改了不同的传递参数,最后都交给on实现的

实现最简单的事件委托

给父元素绑定事件,子元素也能响应

其实委托的原理都是一样的,通过事件对象过滤出关联目标的hack,做相对应的处理,那么JQuery是如何实现的呢?

在绑定阶段与执行阶段

那么JQuery为了更好的对事件的支持内部又做了哪些额外的优化操作?

兼容性问题处理:

浏览器的事件兼容性是一个令人头疼的问题。IE的event在是在全局的window下, 而mozilla的event是事件源参数传入到回调函数中。还有很多的事件处理方式也一样

JQuery提供了一个 event的兼容类方案

jQuery.event.fix 对游览器的差异性进行包装处理

例如:

1. 事件对象的获取兼容,IE的event在是在全局的window,标准的是event是事件源参数传入到回调函数中

2. 目标对象的获取兼容,IE中采用srcElement,标准是target

3. relatedTarget只是对于mouseout、mouseover有用。在IE中分成了to和from两个Target变量,在mozilla中 没有分开。为了保证兼容,采用relatedTarget统一起来

4. event的坐标位置兼容

5. 等等

事件的存储优化:

jQuery并没有将事件处理函数直接绑定到DOM元素上,而是通过.data存储在缓存.data存储在缓存.cahce上,这里就是之前分析的贯穿整个体系的缓存系统了

声明绑定的时候:

· 首先为DOM元素分配一个唯一ID,绑定的事件存储在.cahce[唯一ID][.cahce[唯一ID][.expand ][ 'events' ]上,而events是个键-值映射对象,键就是事件类型,对应的值就是由事件处理函数组成的数组,最后在DOM元素上绑定(addEventListener/ attachEvent)一个事件处理函数eventHandle,这个过程由 jQuery.event.add 实现。

执行绑定的时候:

· 当事件触发时eventHandle被执行,eventHandle再去$.cache中寻找曾经绑定的事件处理函数并执行,这个过程由 jQuery.event. trigger 和 jQuery.event.handle实现。

· 事件的销毁则由jQuery.event.remove 实现,remove对缓存$.cahce中存储的事件数组进行销毁,当缓存中的事件全部销毁时,调用removeEventListener/ detachEvent销毁绑定在DOM元素上的事件处理函数eventHandle。

事件处理器:

jQuery.event.handlers

针对事件委托和原生事件(例如"click")绑定 区分对待

事件委托从队列头部推入,而普通事件绑定从尾部推入,通过记录delegateCount来划分,委托(delegate)绑定和普通绑定。

其余一些兼容事件的Hooks

fixHooks,keyHooks,mouseHooks

总的来说对于JQuery的事件绑定

在绑定的时候做了包装处理

在执行的时候有过滤器处理


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端jQuery频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程