概述
本文详细分析jquery-1.11.1.js源码文件行数:568~5269;
代码简介:JQ原型jQuery.fn利用extend扩展了事件处理的方法on-增加事件监听,off-移除事件监听,trigger-触发事件等可有JQ对象实例调用的方法,这些方法会用each对JQ对象实例里的每一个节点都执行相对应的工具方法,即JQ对象实例的事件处理,是作用于内部所有原生dom节点的;
下文进行详细代码分析。
事件处理的实例方法
// 实例对象的事件处理方法
jQuery.fn.extend({
// 绑定事件方法on(参数one仅限是内部使用,JQ实例对象需要的话可以直接调用后面的one方法)
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
var type, origFn;
// 支持types传入一个map,里面保存types/handlers的场景
if ( typeof types === "object" ) {
// selector不为string的场景( types-Object, selector, data )
if ( typeof selector !== "string" ) {
// 重定义data,假设data为空,则data = selector,( types-Object, data )
data = data || selector;
// 置空selector
selector = undefined;
}
// 遍历对象里的事件类型,逐一调用on
for ( type in types ) {
this.on( type, selector, data, types[ type ], one );
}
return this;
}
// data跟fn同时为空的场景
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;
data = undefined;
} else {
// ( types, data, fn )
fn = data;
data = selector;
selector = undefined;
}
}
if ( fn === false ) {
fn = returnFalse;
} else if ( !fn ) {
return this;
}
// 传入了one的场景
if ( one === 1 ) {
// 先引用原回调
origFn = fn;
// 定义新回调,封装原回调
fn = function( event ) {
// 去除绑定
jQuery().off( event );
// 执行回调
return origFn.apply( this, arguments );
};
// 从之前分析的jQuery.event代码可知,回调里面保存guid,删除的时候用于会判断,这样才知道解除绑定的是不是同一个回调函数
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
}
// 以上各种选择判断分支,均是对不同入参场景进行分类处理
// 最终还是调用each方法,对JQ对象里的每一个元素,执行jQuery.event.add增加绑定事件
return this.each( function() {
jQuery.event.add( this, types, fn, data, selector );
});
},
// one方法,表明事件回调只处理一次
one: function( types, selector, data, fn ) {
return this.on( types, selector, data, fn, 1 );
},
// 解除事件绑定off
off: function( types, selector, fn ) {
var handleObj, type;
if ( types && types.preventDefault && types.handleObj ) {
// ( event ) dispatched jQuery.Event
handleObj = types.handleObj;
jQuery( types.delegateTarget ).off(
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
handleObj.selector,
handleObj.handler
);
return this;
}
if ( typeof types === "object" ) {
// ( types-object [, selector] )
for ( type in types ) {
this.off( type, selector, types[ type ] );
}
return this;
}
if ( selector === false || typeof selector === "function" ) {
// ( types [, fn] )
fn = selector;
selector = undefined;
}
if ( fn === false ) {
fn = returnFalse;
}
// 前面也是兼容各种入参的场景
// 最终同样是使用each对JQ对象每个元素调用jQuery.event.remove解除绑定
return this.each(function() {
jQuery.event.remove( this, types, fn, selector );
});
},
// 触发事件方法trigger
trigger: function( type, data ) {
// 直接使用each方法调用jQuery.event.trigger
return this.each(function() {
jQuery.event.trigger( type, data, this );
});
},
// 会影响到前面event.isTrigger的值,用途暂时不明
triggerHandler: function( type, data ) {
var elem = this[0];
if ( elem ) {
return jQuery.event.trigger( type, data, elem, true );
}
}
});