Mach3.laBlog

実験室: jQuery.triggerを使ってEventDispatcher(AS3)のような事をしてみる

この記事は賞味期限切れです。(更新から1年が経過しています)

AS3にある多くのクラスの中でもお世話になる事が多いのが、EventDispatcher。
カスタムイベントを登録して送出したり出来るので大変便利。
本稿は、JavaScriptでも似た事が出来ないかなぁと試行錯誤してみたログです。

AS3のEventDispatcher

まず、AS3のEventDispatcherはどのような代物なのか。
EventDispatcher – ActionScript 3.0 コンポーネントリファレンスガイド

public class Example extends EventDispatcher {

    public static const EVENT_CHANGE:String = "change";
    private var value:String = "Hello, World!";

    /* 中略 */

    public function setValue( str:String ) : void {
        if ( str !== value ){
            value = str;
            dispatchEvent( new Event( EVENT_CHANGE ) );
        }
    }
}

EventDispatcherは、dispatchEventメソッドを使うことで、
任意のタイミングで、任意のイベントを送出(着火)する事が出来ます。
イベントを受けとるのは、ご存知addEventListenerです。

var obj:Example = new Example();
obj.addEventListener( Example.EVENT_CAHNGE, function( e:Event ){
    trace( "値が変更されました" );
});
obj.setValue("Hello, ActionScript!");

この例では、Example.value の値が変更された時に
「change」イベントが送出(dispatch)されます。
なかなか便利で、重宝しています。

jQueryのtriggerを使ってみる

このdispatchEventに値する物が、jQueryのtriggerです。
.trigger() – jQuery API
clickやsubmit等の既存のイベントは勿論、カスタムイベントの送出も出来ます。

$( element ).bind( "myevent", function(e){
    alert("My Event Fired !");
});
$( element ).trigger("myevent");

せっかくなので(?)、AS3風味に一例書いてみたいと思います。

var obj = function(){};
obj.prototype = {

    EVENT_CHANGE: "change",
    jq:$(this),
    value : "Hello, World !",

    create : function(){
        // do something
        return this;
    },
    setValue : function( str ){
        if( str !== this.value ){
            this.value = str;
            // 値が変更された場合に"change"イベント送出
            this.trigger( this.EVENT_CHANGE );
        }
    },
    bind : function( evt, func ){
        this.jq.bind( evt, func );
    },
    trigger : function( evt ){
        this.jq.trigger( evt );
    }
};

やっている事は基本的に上のASの例と同様で、
保持している値(value)が変更された時に、triggerメソッドでイベントに着火する仕組みです。

「jq:$(this)」の所がちょっと気持ち悪いです…。
jQuery.prototypeを継承してしまおうかとも思ったのですが、
余計なものがボンボコ引き継がれてしまって把握するのが大変なので、このような形に。
もう少しスマートな方法は無いものでしょうか(募集!)。

イベントハンドラの登録は、bindで普通に行ないます。

var myObj = new obj().create();
myObj.bind( myObj.EVENT_CHANGE, function(e){
    alert("値が変更されました。");
});
myObj.setValue("Hello, JavaScript !");

カスタムイベントが上手く使えれば、
オブジェクト同士の連携等も見通しの良いソースで実現できそう。
例えば、外部データと通信・監視させて、データに変更があった時にイベントハンドラを呼ぶ
みたいな実装が、分かりやすく書けそうです。
(そういうのはWebWorkersが得意そうではありますが)

が、やっぱりこういう書き方をするのならPrototype.jsの方が使い勝手は良いですね。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*