博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jQuery Event 模块 源码浅解
阅读量:4677 次
发布时间:2019-06-09

本文共 2961 字,大约阅读时间需要 9 分钟。

    众所周知,jQuery 通过jQuery.event.add & jQuery.event.remove 方法对DOM元素(文本和注释节点除外)进行事件的绑定和解绑。这两个方法都提供了四个参数,前三个参数elem, types, handler 是必选的,最后一个为可选参数分别是data和pos。

绑定:

    jQuery在对DOM元素进行绑定事件时,通过jQuery.data在jQuery.cache中存储绑定的事件类型、响应函数和可选参数data。该数据结构如下:

{    events: {}    handle: function(e){ }}

events是一个对象,events中的属性值存储的是事件类型;值是一个数组。当为DOM元素绑定事件时,首先会创建一个包含响应函数、事件类型、guid和一些附加信息的对象,如果events中不存在值为该事件类型的属性,则添加一个值为该事件类型的属性,和一个值为空的数组,然后将刚创建的新对象push到数组中;如果存在,直接push到相对应的数组中。看下面这个例子就一目了然了:

//给id元素绑定两个单击和一个鼠标离开事件$('#id').bind('click', function() { alert('once');  });$('#id').bind('click', function() { alert('second'); });$('#id').bind('mouseout', function(){ alert('mouseout'); });//events对象的值{    'click': [        {// 此对象还有:data,guid,namespace属性            handler: function() { alert('once'); },            type: 'click'        },        {            handler: function() { alert('second'); },            type: 'click'        }    ],    'mouseout': [        {            handler: function(){ alert('mouseover'); },            type: 'mouseout'        }    ]}

handle是一个函数。jQuery为每一个DOM元素绑定的任意类型事件的响应函数都是此函数,并不是直接将用户传入的函数绑定为响应函数。该函数会在执行时调用一个公共方法jQuery.event.handle,通过apply更改this的指向,此函数还有一个静态属性elem,也是指向DOM元素自己,下面是jQuery中的源码:

//引用自jQuery源码add: function(elem, types, handler, data) {    var elemData = jQuery._data(elem).handle, // 从jQuery.cache中提取的数据        eventHandle = elemData.handle;    // 创建elem对象的事件响应函数    if (!eventHandle) {        elemData.handle = eventHandle = function(e) {            return jQuery.event.handle.apply( eventHandle.elem, arguments ); // 改变对象的this指向        };    }    // handle元素的静态属性elem    eventHandle.elem = elem;    while (type = types[i++]) {        var handlers = events[ type ];        // 查看type类型的事件是否存在        if (!handlers) {            handlers = events[ type ] = [];            // 绑定事件            elem.addEventListener(type, eventHandle, false);        }        handlers.push(handler);    }}

当用户触发事件后,jQuery.event.handle首先会调用jQuery.event.fix对Event对象做兼容处理,之后根据Event.type从jQuery.cache中获取用户绑定时传入的响应函数,逐个运行。

解绑

    主要思路是匹配guid,然后从jQuery.cache中events里删除包含相应的响应函数的对象。最后检查该DOM元素还有没有绑定的事件了,如果没有才是真的removeEventListener掉handle处理函数关删除jQuery.cache中的数据。

 

思考

    通过以上的了解,我们可以看到jQuery再为DOM元素的一种类型事件绑定多个响应函数时只会addEventListener一次,而不需要重复addEventListner,并且该DOM元素的所有类型的事件响应都指向一个函数。这时我的脑子里便浮出了这些问题(这里不谈浏览器兼容上比如IE的内存泄漏之类的问题):这样做的好处是啥?可以减少内存的使用?还是可以提高运行效率?或者说jQuery只是为了对内部事件模块的统一管理?这只是本人所想的到的一些问题, 这样设计肯定有他的考虑。

     接下来,本人就自己所想到的问题进行了思考。我们看看,这样做的唯一一点就是减少了JavaScript引擎对各个DOM元素本身相同类型事件的listening数,用一个对象将DOM元素绑定的响应函数重新组织了下,并增加了一些附加信息。难道说减少listening数可以减少对内存的使用,提高运行效率吗?如果是这样,我们便可以用最老土的方法来进行一些测试,以下是本人的测试方法和数据,仅供参考。

Chrome 11 内存使用/MB 解析时间/ms 处理响应时间/ms
jQuery.bind 17.5 44.75 30.75
addEventListener 21.75 215.75 11.5

 

以上数据是在window下的chrome 11.0.696.65环境中,绑定10 000个事件处理后,测试得到的平均值。当我绑定100 000个事件处理时,使用原生的addEventListener Chrome就提示无影响了,而用jQuery.bind是正常的。

    根据上面的数据,jQuery这样做却实能减少内存的使用和提高JavaScript引擎的解析时间,可是在触发事件后的响应处理要慢一点。

转载于:https://www.cnblogs.com/taberhuang/archive/2011/05/18/2050127.html

你可能感兴趣的文章
CPSR寄存器
查看>>
Java基础50题test7—处理字符串
查看>>
保险行业电话外呼型呼叫中心方案
查看>>
自建型呼叫中心
查看>>
input file 文件上传,js控制上传文件的大小和格式
查看>>
Day 6 函数与模块
查看>>
WebApi请求原理
查看>>
[Node.js] node-persist: localStorage on the server
查看>>
jquery.event 研究学习之bind篇
查看>>
LOJ #108. 多项式乘法
查看>>
libusb开发指南
查看>>
SAS基础 -- 逻辑库不存在问题解决
查看>>
Servlet监听器统计在线人数
查看>>
第2章 数字之魅——寻找发帖“水王”
查看>>
eclipse jsp html 格式化 format
查看>>
关于手机端IOS系统微信中虚拟键盘遮挡input输入框问题的解决方案 草稿
查看>>
css3背景、边框、和补丁相关属性 (二)
查看>>
Python--小功能应用
查看>>
别做操之过急的”无效将军”,做实实在在的”日拱一卒”
查看>>
CLS(公共语言规范)的CLSCompliant(跨语言调用)
查看>>