您的位置:首页 > Web前端 > JQuery

jquery.event 研究学习之bind篇(续 二 )

2012-01-18 23:44 351 查看
继续代码分析,其实上面已经说了。前面是处理参数的琐碎问题说白了是脏活。下面是真的处理事情的时候了。

View Code

var rformElems = /^(?:textarea|input|select)$/i,
rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
rhoverHack = /\bhover(\.\S+)?\b/,
rkeyEvent = /^key/,
rmouseEvent = /^(?:mouse|contextmenu)|click/,
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
quickParse = function( selector ) {
var quick = rquickIs.exec( selector );
if ( quick ) {
//   0  1    2   3
// [ _, tag, id, class ]
quick[1] = ( quick[1] || "" ).toLowerCase();
quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
}
return quick;
},
quickIs = function( elem, m ) {
//
var attrs = elem.attributes || {};
return (
(!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
(!m[2] || (attrs.id || {}).value === m[2]) &&
(!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
);
},
hoverHack = function( events ) {
// hover事件的 主要做hover事件。
return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
};

/*
* Helper functions for managing events -- not part of the public interface.
* Props to Dean Edwards' addEvent library for many of the ideas.
*/
jQuery.event = {
//jQuery.event.add( this, types,    fn,        data, selector );
/*                    |        |         |          |        |
*                    |-对象    |-事件     |-函数      |-参数|-元素(live)
*///                |        |          |          |        |
add: function( elem, types,     handler, data, selector ) {

var elemData, eventHandle, events,
t, tns, type, namespaces, handleObj,
handleObjIn, quick, handlers, special;

// Don't attach events to noData or text/comment nodes (allow plain objects tho)
//不给文本元素添加事件。
if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
return;
}

// Caller can pass in an object of custom data in lieu of the handler
//我理解的是本来以为的函数不是个函数而是个对象。这个对象有这些方法。
//那么应该是JQUERY已经做过的函数,把它重新进行封装。
if ( handler.handler ) {
handleObjIn = handler;//临时存储
handler = handleObjIn.handler;
}

// Make sure that the handler has a unique ID, used to find/remove it later
//还没ID 为它加个ID 。貌似我很久以前是这样做的。不过没这么强大。只是做了ID。
if ( !handler.guid ) {
handler.guid = jQuery.guid++;//增加当前ID
}

// Init the element's event structure and main handler, if this is the first
//    这里是读取所有函数表,如果是第一次读取没有值则定义个空的出来。
events = elemData.events;
if ( !events ) {
elemData.events = events = {};
}
eventHandle = elemData.handle;
if ( !eventHandle ) {//第一次绑定的时候。
/*IMPORT*/            // 这里后面用的到是做的函数序列 。做了个执行顺序的整理等等。。。
elemData.handle = eventHandle = 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 !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
undefined;
};
// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
//把对象做为事件触发的一个属性(Fnx-a.trigger = a)
eventHandle.elem = elem;
}

// Handle multiple events separated by a space
// jQuery(...).bind("mouseover mouseout", fn);
//如果是绑了多个函数的时候 做成数组
types = jQuery.trim( hoverHack(types) ).split( " " );
for ( t = 0; t < types.length; t++ ) {

tns = rtypenamespace.exec( types[t] ) || [];
type = tns[1];
namespaces = ( tns[2] || "" ).split( "." ).sort();
//对名字和函数进行分离 如果用户自己设置了方法名字而不是系统的。触发special
// If event changes its type, use the special event handlers for the changed type
special = jQuery.event.special[ type ] || {};
//如果是动态绑定的
// If selector defined, determine special event api type, otherwise given type
type = ( selector ? special.delegateType : special.bindType ) || type;

// Update special based on newly reset type
special = jQuery.event.special[ type ] || {};

//这里是个结构,对函数,对象,函数ID,函数触发的类型等进行了对应关系。
//我突然想到的竟然是 closure的模块管理,
//我的模块管理是根据那个来的。所以对这非常有印象。
// handleObj is passed to all event handlers
handleObj = jQuery.extend({
type: type,      //type 事件类型 每个都独立处理了?
origType: tns[1],//
data: data,// 默认的数据
handler: handler,//函数
guid: handler.guid,//ID
selector: selector,//元素
quick: quickParse( selector ),//找到元素?
namespace: namespaces.join(".")//名字空间 []
}, handleObjIn );

// Init the event handler queue if we're the first
handlers = events[ type ];
//这是另外的一个表 估计看过模块管理的就知道。每个都是双对应关系表。
if ( !handlers ) {
handlers = events[ type ] = [];
handlers.delegateCount = 0;
//不是特殊的就一般对待。
// Only use addEventListener/attachEvent if the special events handler returns false
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
// Bind the global event handler to the element
if ( elem.addEventListener ) {
//IMPORT 部分的解释。自己对应
elem.addEventListener( type, eventHandle, false );

} else if ( elem.attachEvent ) {
elem.attachEvent( "on" + type, eventHandle );
}
}
}
//特殊对待了。呵呵 这个我和我师傅都写过。
//开始思路清晰了吧。。。主要的是再那些正则表达式
if ( special.add ) {
special.add.call( elem, handleObj );

if ( !handleObj.handler.guid ) {
handleObj.handler.guid = handler.guid;//添加标示
}
}

// Add to the element's handler list, delegates in front
if ( selector ) {
//如果有LIVE
handlers.splice( handlers.delegateCount++, 0, handleObj );
} else {
handlers.push( handleObj );
}

// Keep track of which events have ever been used, for event optimization
//这里也是个记录表。记录哪些方法有绑定。
jQuery.event.global[ type ] = true;
}
//最后晴空万里。。
// Nullify elem to prevent memory leaks in IE
elem = null;
},

global: {},


这里主要还是说到了对应表管理。里面的几个参数我还是不太明白。不过大概思路应该和我的解释类似吧。。我觉得应该是那样的。大大们有不同见解。欢迎来找我讨论下。这个函数部分其实真的很费解的。不过现在看来,应该也不是很难了。

主要 内容:

1. 数据结构。

2. 特殊处理。

3. 参数处理

                                                      ------无代码 ,生活不完美
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: