TypescriptでEventDispatcher作ってみた(javascript)


TypeScriptはFlasherに優しい言語です。
ですが、使える機能はやっぱりjsです。
DomにEventDispatherついてますが、自分で作ったclassに継承とかできません。

という訳で皆さんよく作ってらっしゃる、自作EventDispatcherです。

僕も作ってみました。

```ts:EventDispathcer.ts
module events {
	export class EventDispatcher {
		listeners:any = {};
		dispatchEvent(event: any): void {
			var e:Event;
			var type: string;
			if (event instanceof Event) {
				type = event.type;
				e = event;
			} else {
				type = event;
				e = new Event(type);
			}

			if(this.listeners[type] != null){
				e.currentTarget = this;
				for (var i:number = 0; i < this.listeners[type].length; i++){
					var listener: EventListener = this.listeners[type][i];
						try {
							listener.handler(e);
						} catch (error) {
							if (window.console) {
								console.error(error.stack);
							}
						}
				}
			}
		}

		addEventListener(type: string, callback: Function, priolity: number = 0): void {
			if(this.listeners[type] == null){
				this.listeners[type] = [];
			}


			this.listeners[type].push(new EventListener(type, callback, priolity));
			this.listeners[type].sort(function (listener1:EventListener, listener2:EventListener) {
				return listener2.priolity - listener1.priolity;
			});
		}

		removeEventListener(type:string, callback:Function):void {
			if(this.hasEventListener(type, callback)) {
				for(var i:number=0; i < this.listeners[type].length; i++){
					var listener:EventListener = this.listeners[type][i];
					if(listener.equalCurrentListener(type, callback)) {
						listener.handler = null;
						this.listeners[type].splice(i,1);
						return;
					}
				}
			}
		}

		clearEventListener(): void {
			this.listeners = {};
		}

		containEventListener(type: string): boolean {
			if (this.listeners[type] == null) return false;
			return this.listeners[type].length > 0;
		}

		hasEventListener(type:string, callback:Function):boolean {
			if(this.listeners[type] == null) return false;
			for(var i:number=0; i < this.listeners[type].length; i++){
				var listener:EventListener = this.listeners[type][i];
				if(listener.equalCurrentListener(type, callback)) {
					return true;
				}
			}
			return false;
		}
	}

	class EventListener {
		constructor(public type: string = null, public handler: Function = null, public priolity: number = 0) {
		}
		equalCurrentListener(type: string, handler: Function): boolean {
			if (this.type == type && this.handler == handler) {
				return true;
			}
			return false;
		}
	}

    export class Event {
        currentTarget:any;
        static COMPLETE: string = "complete";
        static CHANGE_PROPERTY:string ="changeProperty";
        constructor(public type: string = null, public value: any = null) {

        }
    }
}
```

使い方は下記のように、EventDispathcerクラスを継承する事で利用できます。
Actionscriptとおんなじ感じですね。

```ts:main.ts
/// <reference path="EventDispatcher.ts"/>
module sample {
    export class BtnSample extends events.EventDispatcher {
        constructor(public dom:HTMLElement) {
            super();
            dom.onclick = ()=>{
                this.btnClick();
            }
        }

        btnClick():void {
            this.dom.innerText = "クリック済み";
            this.dispatchEvent(new events.Event("clicked"));
        }

        getText():string {
            return this.dom.innerText;
        }
    }
}

```

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="btn">ボタン</button>
<script type="text/javascript" src="js/EventDispatcher.js"></script>
<script type="text/javascript" src="js/Main.js"></script>
<script type="text/javascript">
  var btnSample = new sample.BtnSample(document.getElementById("btn"));
  btnSample.addEventListener("clicked", function(){
    alert(btnSample.getText());
  });
</script>
</body>
</html>
```




今後はこれを使って色々サンプルを乗っけていこうと思います。

githubで公開しました。
よろしければ参考にしてみてください。

https://github.com/ts020/tsEventDispacher