mirror of
https://github.com/hiloteam/Hilo.git
synced 2025-12-08 20:35:59 +00:00
141 lines
4.5 KiB
JavaScript
141 lines
4.5 KiB
JavaScript
/**
|
||
* Hilo
|
||
* Copyright 2015 alibaba.com
|
||
* Licensed under the MIT License
|
||
*/
|
||
|
||
/**
|
||
* @class EventMixin是一个包含事件相关功能的mixin。可以通过 Class.mix(target, EventMixin) 来为target增加事件功能。
|
||
* @static
|
||
* @mixin
|
||
* @module hilo/event/EventMixin
|
||
* @requires hilo/core/Class
|
||
*/
|
||
var EventMixin = /** @lends EventMixin# */{
|
||
_listeners: null,
|
||
|
||
/**
|
||
* 增加一个事件监听。
|
||
* @param {String} type 要监听的事件类型。
|
||
* @param {Function} listener 事件监听回调函数。
|
||
* @param {Boolean} once 是否是一次性监听,即回调函数响应一次后即删除,不再响应。
|
||
* @returns {Object} 对象本身。链式调用支持。
|
||
*/
|
||
on: function(type, listener, once){
|
||
var listeners = (this._listeners = this._listeners || {});
|
||
var eventListeners = (listeners[type] = listeners[type] || []);
|
||
for(var i = 0, len = eventListeners.length; i < len; i++){
|
||
var el = eventListeners[i];
|
||
if(el.listener === listener) return;
|
||
}
|
||
eventListeners.push({listener:listener, once:once});
|
||
return this;
|
||
},
|
||
|
||
/**
|
||
* 删除一个事件监听。如果不传入任何参数,则删除所有的事件监听;如果不传入第二个参数,则删除指定类型的所有事件监听。
|
||
* @param {String} type 要删除监听的事件类型。
|
||
* @param {Function} listener 要删除监听的回调函数。
|
||
* @returns {Object} 对象本身。链式调用支持。
|
||
*/
|
||
off: function(type, listener){
|
||
//remove all event listeners
|
||
if(arguments.length == 0){
|
||
this._listeners = null;
|
||
return this;
|
||
}
|
||
|
||
var eventListeners = this._listeners && this._listeners[type];
|
||
if(eventListeners){
|
||
//remove event listeners by specified type
|
||
if(arguments.length == 1){
|
||
delete this._listeners[type];
|
||
return this;
|
||
}
|
||
|
||
for(var i = 0, len = eventListeners.length; i < len; i++){
|
||
var el = eventListeners[i];
|
||
if(el.listener === listener){
|
||
eventListeners.splice(i, 1);
|
||
if(eventListeners.length === 0) delete this._listeners[type];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
/**
|
||
* 发送事件。当第一个参数类型为Object时,则把它作为一个整体事件对象。
|
||
* @param {String} type 要发送的事件类型。
|
||
* @param {Object} detail 要发送的事件的具体信息,即事件随带参数。
|
||
* @returns {Boolean} 是否成功调度事件。
|
||
*/
|
||
fire: function(type, detail){
|
||
var event, eventType;
|
||
if(typeof type === 'string'){
|
||
eventType = type;
|
||
}else{
|
||
event = type;
|
||
eventType = type.type;
|
||
}
|
||
|
||
var listeners = this._listeners;
|
||
if(!listeners) return false;
|
||
|
||
var eventListeners = listeners[eventType];
|
||
if(eventListeners){
|
||
var eventListenersCopy = eventListeners.slice(0);
|
||
event = event || new EventObject(eventType, this, detail);
|
||
if(event._stopped) return false;
|
||
|
||
for(var i = 0; i < eventListenersCopy.length; i++){
|
||
var el = eventListenersCopy[i];
|
||
el.listener.call(this, event);
|
||
if(el.once) {
|
||
var index = eventListeners.indexOf(el);
|
||
if(index > -1){
|
||
eventListeners.splice(index, 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
if(eventListeners.length == 0) delete listeners[eventType];
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 事件对象类。当前仅为内部类,以后有需求的话可能会考虑独立为公开类。
|
||
*/
|
||
var EventObject = Class.create({
|
||
constructor: function EventObject(type, target, detail){
|
||
this.type = type;
|
||
this.target = target;
|
||
this.detail = detail;
|
||
this.timeStamp = +new Date();
|
||
},
|
||
|
||
type: null,
|
||
target: null,
|
||
detail: null,
|
||
timeStamp: 0,
|
||
|
||
stopImmediatePropagation: function(){
|
||
this._stopped = true;
|
||
}
|
||
});
|
||
|
||
//Trick: `stopImmediatePropagation` compatibility
|
||
var RawEvent = window.Event;
|
||
if(RawEvent){
|
||
var proto = RawEvent.prototype,
|
||
stop = proto.stopImmediatePropagation;
|
||
proto.stopImmediatePropagation = function(){
|
||
stop && stop.call(this);
|
||
this._stopped = true;
|
||
};
|
||
}
|