LoginSignup
1
1

More than 3 years have passed since last update.

JavaScriptでEventDispatcher作ってみた

Posted at

はじめに

TypescriptでEventDispatcher作ってみた(javascript)
これがすごくに気にっているので、ES6用にJavaScript移植。

EventDispathcer.js
export class EventDispatcher {
    constructor() {
        this.listeners = {};
    }
    /**
     * イベントをイベントフローに送出します。
     * @param {Event}event ベントフローに送出されるイベントオブジェクトです。
     */
    dispatchEvent(event) {
        let e;
        let type;
        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 (let i = 0; i < this.listeners[type].length; i++){
                let listener = this.listeners[type][i];
                try {
                    listener.handler(e);
                } catch (error) {
                    if (window.console) {
                        console.error(error.stack);
                    }
                }
            }
        }
    }

    /**
     * イベントリスナーオブジェクトを EventDispatcher オブジェクトに登録し、リスナーがイベントの通知を受け取るようにします。
     * @param {string}type イベントのタイプです。
     * @param {function}callback イベントを処理するリスナー関数です。この関数は、次の例のように、Event オブジェクトを唯一のパラメーターとして受け取り、何も返さないものである必要があります。
     * @param {number}priority 優先度
     */
    addEventListener(type, callback, priority = 0) {
        if(this.listeners[type] == null){
            this.listeners[type] = [];
        }
        this.listeners[type].push(new EventListener(type, callback, priority));
        this.listeners[type].sort(function (listener1, listener2) {
            return listener2.priority - listener1.priority;
        });
    }

    /**
     * オブジェクトからリスナーを削除します。
     * @param {string}type イベントのタイプです。
     * @param {function}callback 削除するリスナーオブジェクトです。
     */
    removeEventListener(type, callback) {
        if(this.hasEventListener(type, callback)) {
            for(let i=0; i < this.listeners[type].length; i++){
                let listener = this.listeners[type][i];
                if(listener.equalCurrentListener(type, callback)) {
                    listener.handler = null;
                    this.listeners[type].splice(i,1);
                    return;
                }
            }
        }
    }

    /**
     * リスナーの初期化
     */
    clearEventListener() {
        this.listeners = {};
    }

    /**
     * EventDispatcher オブジェクトに、特定のイベントタイプに対して登録されたリスナーがあるかどうかを確認します。
     * @param {string}type イベントのタイプです。
     * @returns {boolean} 指定したタイプのリスナーが登録されている場合は true、それ以外の場合は false です。
     */
    containEventListener(type) {
        if (this.listeners[type] == null) return false;
        return this.listeners[type].length > 0;
    }

    /**
     * EventDispatcher オブジェクトに、特定のイベントタイプとリスナー関数が登録されたリスナーがあるかどうかを確認します。
     * @param {string}type イベントのタイプです。
     * @param {function}callback
     * @returns {boolean} 指定したタイプとリスナー関数をもつリスナーオブジェクトが登録されている場合は true、それ以外の場合は false です。
     */
    hasEventListener(type, callback) {
        if(this.listeners[type] == null) return false;
        for(let i=0; i < this.listeners[type].length; i++){
            let listener = this.listeners[type][i];
            if(listener.equalCurrentListener(type, callback)) {
                return true;
            }
        }
        return false;
    }
}

/**
 * リスナーの登録オブジェクト
 */
export class EventListener {
    constructor( type = null,  handler = null,  priority = 0) {
        this.type = type;
        this.handler = handler;
    }
    equalCurrentListener(type, handler) {
        if (this.type == type && this.handler == handler) {
            return true;
        }
        return false;
    }
}

/**
 * イベントリスナーにパラメーターとして渡す Event オブジェクトを作成します。
 */
export class Event {
    constructor( type = null,  value = null) {
        this.type = type;
        this.value = value;
        Event.COMPLETE = "complete";
        Event.CHANGE_PROPERTY ="changeProperty";
    }
}

継承したEventは以下の通り。
定数の書き方はclass内はいけないっぽい。

CommonEvent.js
import {Event} from "./EventDispatcher";
export class CommonEvent extends Event{
    constructor(type = null, value = null) {
        super(type, value);
    }
}
//Constant
CommonEvent.MODEL_COMPLETE_EVENT = "model_complete_event";

currentTargetも取れるし、変数も遅れるし、ザクザク開発できそう。
ES6かTypeScrptか悩ましい。

git
https://github.com/kawamurashin/JavaScriptEventDispacher

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1