jQuery-1.9.1源码分析系列(十)事件系统之事件体系结构

2020-05-29 06:56:33易采站长站整理

  2)handleEvent作为element所有事件的“主监听函数”,有它统一管理element上的所有函数。

  3)所有浏览器都支持element[“on” + type]事件绑定方式,跨浏览器兼容。

  好啦,明白了addEvent的事件结构,这个想法确实让人觉得眼前一亮。下面分析jQuery的事件结构

b. jQuery的事件结构

  所有的函数添加事件都会进入jQuery.event.add函数。该函数有两个主要功能:添加事件、附加很多事件相关信息。我们直接上源码,源码思想和Dean Edwards的跨浏览器兼容事件添加处理类似。

  源码分析


add: function( elem, types, handler, data, selector ) {
var tmp, events, t, handleObjIn,
special, eventHandle, handleObj,
handlers, type, namespaces, origType,
//获取elem节点对应的缓存数据
elemData = jQuery._data( elem );
//没有数据或文本/注释节点不能附加事件(但是允许附加普通对象)
if ( !elemData ) {
return;
}
//调用者能通过自定义数据替换handler
if ( handler.handler ) {
handleObjIn = handler;
handler = handleObjIn.handler;
selector = handleObjIn.selector;
}
//确保handler函数有唯一的ID,后续会用来查找/删除这个handler函数
if ( !handler.guid ) {
handler.guid = jQuery.guid++;
}
//如果是初次进入,初始化元素的事件结构和主事件响应入口
if ( !(events = elemData.events) ) {
events = elemData.events = {};
}
if ( !(eventHandle = elemData.handle) ) {
eventHandle = elemData.handle = function( e ) {
//当一个事件被调用后页面已经卸载,则放弃jQuery.event.trigger()的第二个事件,
return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
undefined;
};
//将elem作为handle函数的一个特征防止ie非本地事件引起的内存泄露
eventHandle.elem = elem;
}
//多个事件使用空格隔开的处理
  //如jQuery(...).bind("mouseover mouseout", fn);
  //core_rnotwhite = /S+/g;匹配空白字符
  types = ( types || "" ).match( core_rnotwhite ) || [""];
  t = types.length;
  while ( t-- ) {
//rtypenamespace = /^([^.]*)(?:.(.+)|)$/;
//获取命名空间和原型事件
tmp = rtypenamespace.exec( types[t] ) || [];
type = origType = tmp[1];
namespaces = ( tmp[2] || "" ).split( "." ).sort();
//如果事件改变其类型,使用special事件处理器来处理更改后的事件类型
special = jQuery.event.special[ type ] || {};
//如果选择器已定义,确定special事件API类型,否则给他一个类型
type = ( selector ? special.delegateType : special.bindType ) || type;