此模块用于提供自定义事件,并把实现此接口的对象变成一个事件发送器。
//==================================================
// 事件发送器模块
//==================================================
(function(global,DOC){
var dom = global[DOC.URL.replace(/(#.+|\W)/g,'')];
dom.define("emitter","data", function(){
var fireType = "", blank = ""
var rhoverHack = /\bhover(\.\S+)?/,
rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, reprop = /[a-z]/;
var system = dom.event = {
special:{},//用于处理个别的DOM事件
bind : function( types, handler, selector){
//它将在原生事件发送器或任何能成为事件发送器的普通JS对象添加一个名叫uniqueNumber的属性,用于关联一个缓存体,
//把需要的数据储存到里面,而现在我们就把一个叫@events的对象储放都它里面,
//而这个@event的表将用来放置各种事件类型与对应的回调函数
var target = this, events = dom._data( target) , nativeEmitter = dom["@emitter"] in target,
all, tns ,type, namespace, special, handlerObj, handlers, fn;
if(target.nodeType === 3 || target.nodeType === 8 || !types || typeof handler !=="function" || !events) return ;
all = {
handler:handler,
uuid: dom.uuid++
}
//确保UUID,bag与callback的UUID一致
all.handler.uuid = all.uuid;
if(nativeEmitter ){
//处理DOM事件
fn = events.handle || (events.handle = function( e ) {
return ((e || event).type !== fireType) ? system.handle.apply( fn.target, arguments ) :void 0;
});
fn.target = target;
types = types.replace( rhoverHack, "mouseover$1 mouseout$1" )
}
events = events.events || (events.events = {});
//对多个事件进行绑定
types.replace(dom.rword,function(type){
tns = rtypenamespace.exec( type ) || [];
type = tns[1];//取得事件类型
namespace = (tns[2] || "").split( "." ).sort();//取得命名空间
//事件冒充只用于原生事件发送器
special = nativeEmitter && system.special[ type ] || {};
type = (selector? special.delegateType : special.bindType ) || type;
special = nativeEmitter && system.special[ type ] || {};
handlerObj = dom.mix({
type: type,
origType: tns[1],
selector: selector,
namespace: namespace.join(".")
}, all);
//创建事件队列
handlers = events[ type ] = events[ type ] || [];
//只有原生事件发送器才能进行DOM level2 多投事件绑定
if(nativeEmitter && !handlers.length ){
if (!special.setup || special.setup( target, selector, fn ) === false ) {
// 为此元素这种事件类型绑定一个全局的回调,用户的回调则在此回调中执行
dom.bind(target,type,fn,!!selector)
}
}
handlers.push( handlerObj );
});
},
unbind: function( types, handler, selector ) {
var target = this, events = dom._data( target,"events")
if(!events) return;
var t, tns, type, namespace, origCount,nativeEmitter = dom["@emitter"] in target,
j, special, handlers, handlerObj;
types = nativeEmitter ? (types || "").replace( rhoverHack, "mouseover$1 mouseout$1" ) : types;
types = (types || "").split(" ");
for ( t = 0; t