jsdk-offical
Version:
JSDK is the most comprehensive TypeScript framework, like JDK.
170 lines (157 loc) • 6.05 kB
text/typescript
/**
* @project JSDK
* @license MIT
* @website https://github.com/fengboyue/jsdk
*
* @version 2.0.0
* @author Frank.Feng
*/
/// <reference path="../util/Check.ts"/>
/// <reference path="../util/Arrays.ts"/>
module JS {
export namespace util {
//为每个事件监听函数生成uid,方便以后注销
//这是一个全局计数器
let EUID = 1, E = Check.isEmpty;
export type EventHandler<T=any> = (this: T, e: Event, ...args:any[]) => boolean | void;
export type EventHandler1<T, ARG1> = (this: T, e: Event, ARG1) => boolean | void;
export type EventHandler2<T, ARG1, ARG2> = (this: T, e: Event, ARG1, ARG2) => boolean | void;
export type EventHandler3<T, ARG1, ARG2, ARG3> = (this: T, e: Event, ARG1, ARG2, ARG3) => boolean | void;
export class EventBus {
private _ctx: any;
private _isD = false;
private _map = new Map<string, Function[]>();
constructor(context?: any) {
this._ctx = Jsons.clone(context);
}
public context(): any
public context(ctx: any): void
public context(ctx?: any): any {
if (arguments.length == 0) return this._ctx;
this._ctx = ctx;
}
/**
* 销毁自身
*/
public destroy() {
this.off();
this._ctx = null;
this._isD = true;
}
/**
* 是否已销毁
*/
public isDestroyed() {
return this._isD;
}
private _add(type: string, h: EventHandler) {
let fns = this._map.get(type) || [];
fns[fns.length] = h;
this._map.set(type, fns);
}
private _remove(type: string, h?: EventHandler) {
if (!h) {
this._map.set(type, []);
} else {
let fns = this._map.get(type);
if (!E(fns)) {
fns.remove(fn => {
return fn['euid'] === h['euid']
})
this._map.set(type, fns);
}
}
}
private _removeByEuid(type: string, euid: number) {
let fns = this._map.get(type);
if (!E(fns)) {
fns.remove(fn => {
return fn['euid'] === euid
})
this._map.set(type, fns);
}
}
private _euid(h: EventHandler, one: boolean, type: string) {
let me = this,
euid = h['euid'] || EUID++,
fn = function () {
if (one) me._removeByEuid(type, euid);
return h.apply(this, arguments);
};
fn['euid'] = h['euid'] = euid;
return fn
}
public on<H=EventHandler>(types: string, handler: H, once?:boolean): boolean {
if (this.isDestroyed()) return false;
types.split(' ').forEach((tp) => {
this._add(tp, this._euid(<any>handler, once, tp))
})
return true
}
/**
* Returns original event listeners of the type.
* @param type
*/
public original(type:string):EventHandler[]
/**
* Returns original event listener of the type and euid.
* @param type
* @param euid Wrapped listener's uuid
*/
public original(type:string, euid:number):EventHandler
public original(type:string, euid?:number):any{
let fns = this._map.get(type);
if(arguments.length>=1){
if (!E(fns)) {
let i = fns.findIndex(fn => {
return fn['euid'] === euid
})
if(i>-1) return <any>fns[i]
}
return null
}
return fns||null
}
public types(){
return Array.from(this._map.keys())
}
public off(types?: string, handler?: EventHandler): boolean {
if (this.isDestroyed()) return false;
if (types) {
types.split(' ').forEach((tp) => {
this._remove(tp, handler)
})
} else {
this._map.clear()
}
return true
}
private _call(e: Event | CustomEvent, fn: Function, args?: Array<any>, that?: any) {
let evt = e['originalEvent'] ? e['originalEvent'] : e,//for jQuery.Event
arr = [evt];
if (args && args.length > 0) arr = arr.concat(args);
let rst = fn.apply(that||this._ctx, arr);
if(rst===false) {
evt.stopPropagation();
evt.preventDefault()
}
}
public fire(e: string | Event, args?: Array<any>, that?: any) {
let is = Types.isString(e),
fns = this._map.get(is ? <string>e : (<Event>e).type);
if (!E(fns)) {
let evt = is ? new CustomEvent(<string>e) : (<Event>e);
fns.forEach(
fn => {this._call(evt, fn, args, that)}
)
}
}
}
}
}
//预定义短类名
import EventHandler = JS.util.EventHandler;
import EventHandler1 = JS.util.EventHandler1;
import EventHandler2 = JS.util.EventHandler2;
import EventHandler3 = JS.util.EventHandler3;
import EventBus = JS.util.EventBus;