前言:我用的jQuery版本为v2.0.1,jQuery绑定事件的接口有bind/delegate/click等其他方法,但是他们最终调用的还是this.on作为入口
但是jQuery提供两种绑定机制
1.普通事件绑定
2.委托绑定事件
这两中的区别有很大的不同,只是在作用上。委托绑定事件机制能给浏览器带来很大的性能优化。不过两种可以防止浏览器的内存泄露( 特别是在IE中)
今天我用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 ) : // click null callback undefined
this.trigger( name );
};
});
1.jQuery用简写模式,使基本事件函数循环到jQuery..fn中,可以让外部调用
二:// jquery on
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
// click null callback undefined undefined
// click 'a' callback undefined undefined
var type, origFn;
// Types can be a map of types/handlers
if ( typeof types === "object" ) {
// ( types-Object, selector, data )
if ( typeof selector !== "string" ) {
// ( types-Object, data )
data = data || selector;
selector = undefined;
}
for ( type in types ) {
this.on( type, selector, data, types[ type ], one );
}
return this;
}
// 参数调整
if ( data == null && fn == null ) {
// ( types, fn )
fn = selector;
data = selector = undefined;
} else if ( fn == null ) {
if ( typeof selector === "string" ) {
// ( types, selector, fn )
fn = data; // callback
data = undefined; // undefined
} else {
// ( types, data, fn )
fn = data; // callback
data = selector; // null
selector = undefined; // undefined
}
}
if ( fn === false ) {
fn = returnFalse;
} else if ( !fn ) {
return this;
}
if ( one === 1 ) {
origFn = fn;
fn = function( event ) {
// Can use an empty set, since event contains the info
jQuery().off( event );
return origFn.apply( this, arguments );
};
// Use same guid so caller can remove using origFn
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
}
return this.each( function() {
// elem , click,callback,null,undefined
// elem , click,callback,null,'a'
jQuery.event.add( this, types, fn, data, selector );
});
},
1.this.on()大部分工作主要是修复参数.
2.主要绑定工作在 jQuery.event.add( this, types, fn, data, selector );中
三:// elem,click,callback,null,undefined
// elem,click,callback,null,'a'
add: function( elem, types, handler, data, selector ) {
var tmp, events, t, handleObjIn,
special, eventHandle, handleObj,
handlers, type, namespaces, origType,
elemData = jQuery._data( elem ); // {} 空对象 == jQuery.cache[id]
// Don't attach events to noData or text/comment nodes (but allow plain objects)
if ( !elemData ) {
return;
}
// Caller can pass in an object of custom data in lieu of the handler
if ( handler.handler ) {
handleObjIn = handler;
handler = handleObjIn.handler;
selector = handleObjIn.selector;
}
// Make sure that the handler has a unique ID, used to find/remove it later
if ( !handler.guid ) {
handler.guid = jQuery.guid++; // 2
}
// Init the element's event structure and main handler, if this is the first
if ( !(events = elemData.events) ) {
events = elemData.events = {}; // 初始化为空对象
}
if ( !(eventHandle = elemData.handle) ) {
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 !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : // elem event
undefined;
};
// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
eventHandle.elem = elem;
}