1 2 /** 3 * @class EventMixin是一个包含事件相关功能的mixin。可以通过 Class.mix(target, EventMixin) 来为target增加事件功能。 4 * @mixin 5 * @static 6 * @module hilo/event/EventMixin 7 * @requires hilo/core/Class 8 */ 9 var EventMixin = { 10 _listeners: null, 11 12 /** 13 * 增加一个事件监听。 14 * @param {String} type 要监听的事件类型。 15 * @param {Function} listener 事件监听回调函数。 16 * @param {Boolean} once 是否是一次性监听,即回调函数响应一次后即删除,不再响应。 17 */ 18 on: function(type, listener, once){ 19 var listeners = (this._listeners = this._listeners || {}); 20 var eventListeners = (listeners[type] = listeners[type] || []); 21 for(var i = 0, len = eventListeners.length; i < len; i++){ 22 var el = eventListeners[i]; 23 if(el.listener === listener) return; 24 } 25 eventListeners.push({listener:listener, once:once}); 26 return this; 27 }, 28 29 /** 30 * 删除一个事件监听。如果不传入任何参数,则删除所有的事件监听;如果不传入第二个参数,则删除指定类型的所有事件监听。 31 * @param {String} type 要删除监听的事件类型。 32 * @param {Function} listener 要删除监听的回调函数。 33 */ 34 off: function(type, listener){ 35 //remove all event listeners 36 if(arguments.length == 0){ 37 this._listeners = null; 38 return this; 39 } 40 41 var eventListeners = this._listeners && this._listeners[type]; 42 if(eventListeners){ 43 //remove event listeners by specified type 44 if(arguments.length == 1){ 45 delete this._listeners[type]; 46 return this; 47 } 48 49 for(var i = 0, len = eventListeners.length; i < len; i++){ 50 var el = eventListeners[i]; 51 if(el.listener === listener){ 52 eventListeners.splice(i, 1); 53 if(eventListeners.length === 0) delete this._listeners[type]; 54 break; 55 } 56 } 57 } 58 return this; 59 }, 60 61 /** 62 * 发送事件。当第一个参数类型为Object时,则把它作为一个整体事件对象。 63 * @param {String} type 要发送的事件类型。 64 * @param {Object} detail 要发送的事件的具体信息,即事件随带参数。 65 */ 66 fire: function(type, detail){ 67 var event, eventType; 68 if(typeof type === 'string'){ 69 eventType = type; 70 }else{ 71 event = type; 72 eventType = type.type; 73 } 74 75 var listeners = this._listeners; 76 if(!listeners) return false; 77 78 var eventListeners = listeners[eventType]; 79 if(eventListeners){ 80 eventListeners = eventListeners.slice(0); 81 event = event || new EventObject(eventType, this, detail); 82 83 for(var i = 0; i < eventListeners.length && !event._stopped; i++){ 84 var el = eventListeners[i]; 85 el.listener.call(this, event); 86 if(el.once) eventListeners.splice(i--, 1); 87 } 88 89 if(eventListeners.length == 0) delete listeners[eventType]; 90 return true; 91 } 92 return false; 93 } 94 }; 95 96 /** 97 * 事件对象类。当前仅为内部类,以后有需求的话可能会考虑独立为公开类。 98 */ 99 var EventObject = Class.create({ 100 constructor: function EventObject(type, target, detail){ 101 this.type = type; 102 this.target = target; 103 this.detail = detail; 104 this.timeStamp = +new Date(); 105 }, 106 107 type: null, 108 target: null, 109 detail: null, 110 timeStamp: 0, 111 112 stopImmediatePropagation: function(){ 113 this._stopped = true; 114 } 115 }); 116