原帖地址:http://space.flash8.net/space/?18713/viewspace-403269.html
原作者:我佛山人
//
Element事件的setter,addEvents的快捷方式
Element.Properties.events = {set: function (events) {
this .addEvents(events);
}};
// Element、Window 和 Document的事件扩展
Native.implement([Element, Window, Document], {
// 添加事件监听,有别于addListener,可以使用自定义事件
addEvent: function (type, fn) {
// 取临时对象,注意提供的默认值
var events = this .retrieve( ' events ' , {});
// 查找指定类型的事件列表
events[type] = events[type] || { ' keys ' : [], ' values ' : []};
// 如果已经添加了该监听
if (events[type].keys.contains(fn)) return this ;
// 添加到事件订阅列表
events[type].keys.push(fn);
var realType = type, custom = Element.Events.get(type), condition = fn, self = this ;
// 如果是自定义事件
if (custom) {
// 添加自定义事件时的处理
if (custom.onAdd) custom.onAdd.call( this , fn);
// 自定义事件的条件
if (custom.condition) {
condition = function (event) {
if (custom.condition.call( this , event)) return fn.call( this , event);
return false ;
};
}
realType = custom.base || realType;
}
var defn = function () {
return fn.call(self);
};
// 内置事件类型处理
var nativeEvent = Element.NativeEvents[realType] || 0 ;
// 如果是内置的事件
if (nativeEvent) {
// 如果是交互事件
if (nativeEvent == 2 ) {
// 闭包
defn = function (event) {
// 这样最后传给监听函数的参数是经包装过Event对象
event = new Event(event, self.getWindow());
// 这个条件用于扩展内置事件
if (condition.call(self, event) === false ) event.stop();
};
}
// 最终还是调用addListener
this .addListener(realType, defn);
}
// 添加到列表
events[type].values.push(defn);
return this ;
},
// 移除事件监听
removeEvent: function (type, fn) {
// 取临时对象,不提供默认值
var events = this .retrieve( ' events ' );
// 如果临时对象不存在,说明监听不存在,直接返回
if ( ! events || ! events[type]) return this ;
// 检查是否已添加本监听
var pos = events[type].keys.indexOf(fn);
// 没有则返回
if (pos == - 1 ) return this ;
// 从队列中移除
var key = events[type].keys.splice(pos, 1 )[ 0 ];
var value = events[type].values.splice(pos, 1 )[ 0 ];
// 自定义事件处理
var custom = Element.Events.get(type);
// 如果是自定义事件
if (custom) {
// 自定义事件的移除处理
if (custom.onRemove) custom.onRemove.call( this , fn);
type = custom.base || type;
}
// 如果是内置事件还需要调用removeListener来处理
return (Element.NativeEvents[type]) ? this .removeListener(type, value) : this ;
},
// 批量添加事件监听
addEvents: function (events) {
for ( var event in events) this .addEvent(event, events[event]);
return this ;
},
// 批量移除事件监听
removeEvents: function (type) {
// 取临时对象,不提供默认值
var events = this .retrieve( ' events ' );
// 没有事件监听直接返回
if ( ! events) return this ;
// 如果不提供type参数,移除所有类型的事件
if ( ! type) {
for ( var evType in events) this .removeEvents(evType);
events = null ;
} else if (events[type]) {
// 移除指定类型的事件
while (events[type].keys[ 0 ]) this .removeEvent(type, events[type].keys[ 0 ]);
events[type] = null ;
}
return this ;
},
// 事件通知
fireEvent: function (type, args, delay) {
// 取临时对象,不提供默认值
var events = this .retrieve( ' events ' );
// 没有事件监听
if ( ! events || ! events[type]) return this ;
events[type].keys.each( function (fn) {
// 注意事件监听的函数中this默认指向当前Element
fn.create({ ' bind ' : this , ' delay ' : delay, ' arguments ' : args})();
}, this );
return this ;
},
// 事件复制
cloneEvents: function (from, type) {
// 事件源
from = $(from);
var fevents = from.retrieve( ' events ' );
if ( ! fevents) return this ;
// 不提供type参数则复制所有事件
if ( ! type) {
for ( var evType in fevents) this .cloneEvents(from, evType);
} else if (fevents[type]) {
// 复制指定类型的事件
fevents[type].keys.each( function (fn) {
this .addEvent(type, fn);
}, this );
}
return this ;
}
});
// 内置事件,分两种类型
Element.NativeEvents = {
click: 2 , dblclick: 2 , mouseup: 2 , mousedown: 2 , contextmenu: 2 , // mouse buttons
mousewheel: 2 , DOMMouseScroll: 2 , // mouse wheel
mouseover: 2 , mouseout: 2 , mousemove: 2 , selectstart: 2 , selectend: 2 , // mouse movement
keydown: 2 , keypress: 2 , keyup: 2 , // keyboard
focus: 2 , blur: 2 , change: 2 , reset: 2 , select: 2 , submit: 2 , // form elements
load: 1 , unload: 1 , beforeunload: 1 , resize: 1 , move: 1 , DOMContentLoaded: 1 , readystatechange: 1 , // window
error: 1 , abort: 1 , scroll: 1 // misc
};
// 就地执行的匿名函数
( function () {
var $check = function (event) {
var related = event.relatedTarget;
if (related == undefined) return true ;
if (related === false ) return false ;
return ($type( this ) != ' document ' && related != this && related.prefix != ' xul ' && ! this .hasChild(related));
};
// 基于原事件扩展出的自定义事件
Element.Events = new Hash({
// 鼠标进入事件
mouseenter: {
base: ' mouseover ' ,
condition: $check
},
// 鼠标离开事件
mouseleave: {
base: ' mouseout ' ,
condition: $check
},
// 鼠标滚轮事件
mousewheel: {
base: (Browser.Engine.gecko) ? ' DOMMouseScroll ' : ' mousewheel '
}
});
})();
Element.Properties.events = {set: function (events) {
this .addEvents(events);
}};
// Element、Window 和 Document的事件扩展
Native.implement([Element, Window, Document], {
// 添加事件监听,有别于addListener,可以使用自定义事件
addEvent: function (type, fn) {
// 取临时对象,注意提供的默认值
var events = this .retrieve( ' events ' , {});
// 查找指定类型的事件列表
events[type] = events[type] || { ' keys ' : [], ' values ' : []};
// 如果已经添加了该监听
if (events[type].keys.contains(fn)) return this ;
// 添加到事件订阅列表
events[type].keys.push(fn);
var realType = type, custom = Element.Events.get(type), condition = fn, self = this ;
// 如果是自定义事件
if (custom) {
// 添加自定义事件时的处理
if (custom.onAdd) custom.onAdd.call( this , fn);
// 自定义事件的条件
if (custom.condition) {
condition = function (event) {
if (custom.condition.call( this , event)) return fn.call( this , event);
return false ;
};
}
realType = custom.base || realType;
}
var defn = function () {
return fn.call(self);
};
// 内置事件类型处理
var nativeEvent = Element.NativeEvents[realType] || 0 ;
// 如果是内置的事件
if (nativeEvent) {
// 如果是交互事件
if (nativeEvent == 2 ) {
// 闭包
defn = function (event) {
// 这样最后传给监听函数的参数是经包装过Event对象
event = new Event(event, self.getWindow());
// 这个条件用于扩展内置事件
if (condition.call(self, event) === false ) event.stop();
};
}
// 最终还是调用addListener
this .addListener(realType, defn);
}
// 添加到列表
events[type].values.push(defn);
return this ;
},
// 移除事件监听
removeEvent: function (type, fn) {
// 取临时对象,不提供默认值
var events = this .retrieve( ' events ' );
// 如果临时对象不存在,说明监听不存在,直接返回
if ( ! events || ! events[type]) return this ;
// 检查是否已添加本监听
var pos = events[type].keys.indexOf(fn);
// 没有则返回
if (pos == - 1 ) return this ;
// 从队列中移除
var key = events[type].keys.splice(pos, 1 )[ 0 ];
var value = events[type].values.splice(pos, 1 )[ 0 ];
// 自定义事件处理
var custom = Element.Events.get(type);
// 如果是自定义事件
if (custom) {
// 自定义事件的移除处理
if (custom.onRemove) custom.onRemove.call( this , fn);
type = custom.base || type;
}
// 如果是内置事件还需要调用removeListener来处理
return (Element.NativeEvents[type]) ? this .removeListener(type, value) : this ;
},
// 批量添加事件监听
addEvents: function (events) {
for ( var event in events) this .addEvent(event, events[event]);
return this ;
},
// 批量移除事件监听
removeEvents: function (type) {
// 取临时对象,不提供默认值
var events = this .retrieve( ' events ' );
// 没有事件监听直接返回
if ( ! events) return this ;
// 如果不提供type参数,移除所有类型的事件
if ( ! type) {
for ( var evType in events) this .removeEvents(evType);
events = null ;
} else if (events[type]) {
// 移除指定类型的事件
while (events[type].keys[ 0 ]) this .removeEvent(type, events[type].keys[ 0 ]);
events[type] = null ;
}
return this ;
},
// 事件通知
fireEvent: function (type, args, delay) {
// 取临时对象,不提供默认值
var events = this .retrieve( ' events ' );
// 没有事件监听
if ( ! events || ! events[type]) return this ;
events[type].keys.each( function (fn) {
// 注意事件监听的函数中this默认指向当前Element
fn.create({ ' bind ' : this , ' delay ' : delay, ' arguments ' : args})();
}, this );
return this ;
},
// 事件复制
cloneEvents: function (from, type) {
// 事件源
from = $(from);
var fevents = from.retrieve( ' events ' );
if ( ! fevents) return this ;
// 不提供type参数则复制所有事件
if ( ! type) {
for ( var evType in fevents) this .cloneEvents(from, evType);
} else if (fevents[type]) {
// 复制指定类型的事件
fevents[type].keys.each( function (fn) {
this .addEvent(type, fn);
}, this );
}
return this ;
}
});
// 内置事件,分两种类型
Element.NativeEvents = {
click: 2 , dblclick: 2 , mouseup: 2 , mousedown: 2 , contextmenu: 2 , // mouse buttons
mousewheel: 2 , DOMMouseScroll: 2 , // mouse wheel
mouseover: 2 , mouseout: 2 , mousemove: 2 , selectstart: 2 , selectend: 2 , // mouse movement
keydown: 2 , keypress: 2 , keyup: 2 , // keyboard
focus: 2 , blur: 2 , change: 2 , reset: 2 , select: 2 , submit: 2 , // form elements
load: 1 , unload: 1 , beforeunload: 1 , resize: 1 , move: 1 , DOMContentLoaded: 1 , readystatechange: 1 , // window
error: 1 , abort: 1 , scroll: 1 // misc
};
// 就地执行的匿名函数
( function () {
var $check = function (event) {
var related = event.relatedTarget;
if (related == undefined) return true ;
if (related === false ) return false ;
return ($type( this ) != ' document ' && related != this && related.prefix != ' xul ' && ! this .hasChild(related));
};
// 基于原事件扩展出的自定义事件
Element.Events = new Hash({
// 鼠标进入事件
mouseenter: {
base: ' mouseover ' ,
condition: $check
},
// 鼠标离开事件
mouseleave: {
base: ' mouseout ' ,
condition: $check
},
// 鼠标滚轮事件
mousewheel: {
base: (Browser.Engine.gecko) ? ' DOMMouseScroll ' : ' mousewheel '
}
});
})();