Modelと互換性をもたせるために変更されました(MDN「EventTarget.dispatchEvent()メソッド」参照)。0.8.0では、送られるイベントオブジェクトのEvent.defaultPreventedプロパティの値が返されました。0.8.1のEventDispatcher.dispatchEvent()メソッドの実装はつぎのとおりで、戻り値の真偽が逆になるのでご注意ください。!eventObj.defaultPrevented;};説明EventDispatcherクラスは、イベントごとに加えられたリスナーを取りまとめ、イベントが起こったときそれぞれのリスナーに配信します。DisplayObjectは、EventDispatcherクラスを継承してイベントリスナーを扱います。他方、Tickerクラスは静的メソッドEventDispatcher.initialize()により、EventDispatcherクラスの備えるメソッド群をクラスのプロトタイプオブジェクトに加えています。EventDispatcher.addEventListener()メソッドでイベントに加えたリスナー関数は、「グローバル・オブジェクト」上で呼出されます。したがって、Webブラウザでは、リスナー関数の中のthis参照はWindowオブジェクトを指します。関数の中のthis参照を変えたいときには、EventDispatcher.addEventListener()メソッドの第2引数に渡すリスナーにFunction.bind()メソッドで参照すべきオブジェクトを定めます(ただし、「EaselJSのイベントリスナーにFunction.bind()メソッドを適用するとリスナー内から削除できない」ことにご注意ください)。EventDispatcher.on()メソッドは、第2引数の関数から新たなリスナー関数をつくって第1引数のイベントに加えます。呼出されるリスナー関数の中のthis参照は、第3引数で定まります。デフォルトでは、リスナーが関数の場合はメソッドの参照するオブジェクト、リスナーがオブジェクトのときはそのオブジェクトになります。メソッドの戻り値は、新たにつくられたリスナー関数です。イベントリスナーを除くときには、この関数の参照を渡さなければなりません。リスナーにオブジェクトを加えると、そのオブジェクトに備わるhandleEvent()メソッドが呼出されます。Stageクラスには内部的にhandleEvent()メソッドが定められており、Stage.update()メソッドを呼出します(後述「実装」参照)。したがって、Ticker.tickイベントのリスナーにStageオブジェクトを加えれば、Stage.update()メソッドがイベントごとに繰返し呼出せます。静的メソッドEventDispatcher.initialize()に、クラス(コンストラクタ関数)のプロトタイプオブジェクト(Function.prototypeプロパティ)またはインスタンスを渡して呼出すと、EventDispatcherクラスのつぎの8つのメソッドが備わります(厳密には、後述「実装」のとおり、内部的なメソッドがもうひとつ加えられます)。EventDispatcher.addEventListener()EventDispatcher.on()EventDispatcher.removeEventListener()EventDispatcher.off()EventDispatcher.removeAllEventListeners()EventDispatcher.hasEventListener()EventDispatcher.dispatchEvent()EventDispatcher.willTrigger()例つぎのスクリプトは、インスタンス(instance)のDisplayObject.clickイベント("click")に、EventDispatcher.addEventListener()メソッドでリスナー関数(clickHandler())を加えます。すると、インスタンスをクリックしたとき、イベントリスナーが呼出されます。リスナー関数は、引数に受取ったイベントオブジェクトのEvent.targetプロパティから、クリックしたインスタンスの参照(instance)を得ます。処理を終えた後、EventDispatcher.removeEventListener()メソッドでインスタンスのこのイベントからリスナーを除いています。したがって、この後インスタンスをクリックしても、関数は呼出されません。clickHandler);}つぎのスクリプトは、インスタンス(instance)のDisplayObject.clickイベント("click")に、EventDispatcher.on()メソッドでリスナー関数(clickHandler())を加えます。インスタンスをクリックしたとき、イベントリスナーは第3引数のオブジェクト(data)をthis参照として呼出されます。メソッドの第5引数に与えた値(30)は、リスナー関数が第2引数として受取ります。リスナー関数(clickHandler())は、第1引数に受取ったイベントオブジェクト(eventObject)からクリックしたインスタンスの参照(instance)を得て、その角度を第2引数(angle)の値回します。this参照のカウンタのプロパティ(count)を1加算して、値が1を超えるとEventDispatcher.removeEventListener()メソッドでインスタンスのこのイベントからリスナーを除きます[*2]。したがって、インスタンスが回るのは、クリック2回だけになります。EventDispatcher.removeEventListener()メソッドの第2引数に渡すリスナー関数が、this参照に定めたオブジェクトのプロパティ(listener)から取出されていることにご注目ください。コードの初めの4行を関数内に書いて、EventDispatcher.on()メソッドの第3引数に引数に渡すオブジェクト(data)をローカル変数に納めたとしても、オブジェクトの参照は保たれます。Event.set()メソッドでオブジェクトにプロパティをまとめて加える」の「例」をご参照ください。呼出されたリスナー関数自身をイベントから除くには、Event.remove()メソッドを用いることもできます(後述「実装」のEventDispatcher.on()メソッド参照)。Event.remove()メソッドは直ちにイベントリスナーを消さないことにご注意ください。そのイベントリスナーをもう呼出さないというフラグが与えられるだけです。内部的には、つぎにイベントが配信されるとき、フラグのついたリスナーが除かれます。そのため、Event.remove()メソッドを呼出したすぐ後にEventDispatcher.hasEventListener()メソッドでリスナーがあるか調べると、trueが返されてリスナーは残っています。実装EventDispatcherクラスの以下の3つのメソッドについて、バージョン0.7.0にもとづき、その実装をかいつまんでご説明します。●EventDispatcher.addEventListener()メソッドイベントリスナーは、内部的なプロパティでキャプチャフェーズ(_captureListeners)とそれ以外(_listeners)に分けてオブジェクトとして納められています。それらのオブジェクトには、イベント名のプロパティに配列が与えられ、リスナーはその配列エレメントに加えられます。そこで、EventDispatcher.addEventListener()メソッドは、第3引数(useCapture)に応じてリスナーが納められたオブジェクトの参照を変数(listeners)に得て、指定のイベント(type)のプロパティで定められた配列(arr)を取出します。メソッドが第2引数に受取ったリスナー(listener)を、その配列に納めています。EventDispatcher.addEventListener()メソッドは、加えたリスナーを返します。listener;};なお、リスナーを納めるオブジェクトがまだないときは、新たなオブジェクトがつくられてプロパティ(_captureListenersまたは_listeners)に与えられます。論理和演算子||を用いた初期値の代入については、「論理演算子を使った条件判定」02「初期化されていない変数に値を与える」をご参照ください。●EventDispatcher.on()メソッドEventDispatcher.on()メソッドは、第2引数のリスナー(listener)から、他の引数にもとづく新たな関数をつくり、第1引数(type)のイベントのリスナーとして加えます。第2引数のリスナーがhandleEvent()メソッドをもつオブジェクトのときは、そのメソッドをリスナー関数とします。スコープ(scope)のデフォルト値は、リスナーオブジェクトです。つぎに、第2引数が関数の場合には、スコープのデフォルト値をthis参照とします。内部的にEventDispatcher.addEventListener()メソッドを呼出します。第1引数に受取ったイベントはそのまま渡し、リスナーを名前のない関数で定めています。proxy()メソッド」の「実装」参照)。受取った第4引数(once)がtrueのときは、Event.remove()メソッドでイベントリスナーから除きます。EventDispatcher.addEventListener()メソッドは、イベントに加えたリスナーを返すので、その関数をEventDispatcher.on()メソッドの戻り値とします。useCapture);};なお、論理積演算子&&によるメソッドの呼び出しについては、「論理演算子を使った条件判定」01「関数があったら呼出す」をご参照ください。●EventDispatcher.initialize()メソッドEventDispatcher.initialize()メソッドは、引数に渡されたオブジェクトに、EventDispatcherクラスのイベントリスナーを扱うメソッドを加えます。EventDispatcherクラスのプロトタイプオブジェクト(Function.prototypeプロパティ)から9つのメソッドの参照を、同じ名前で引数のオブジェクトに与えます[*3]。_dispatchEvent()メソッドは、EventDispatcher.dispatchEvent()メソッドから内部的に呼出されます。EventDispatcher.prototype.willTrigger;};Tickerクラスは初期化されるときに、クラス(コンストラクタ)をEventDispatcher.initialize()メソッドに渡して、EventDispatcherクラスのメソッドを実装しています。createjs.EventDispatcher.initialize(Ticker);●Stage.handleEvent()メソッド(内部実装)ご参考までに、ドキュメントに掲載されず、内部的に定められたStageクラスのメソッドhandleEvent()の実装をご紹介します。Ticker.tickイベントにリスナーとして加えられ、引数に受取ったイベントオブジェクトのtypeプロパティ値が"tick"であることを確かめると、Stage.update()メソッドが呼出されます。このようにしてクラスのメソッドを他のクラスに加える手法は「Mixin」と呼ばれます。他のクラスを継承しているとき、さらに別のクラスのプロパティやメソッドが使いたい場合に便利です。0.8.1にもとづいて改訂。タイトルのバージョンも改めた。タイトルを「EaselJSでイベントリスナーを扱うEventDispatcherクラス」から改題。0.7.0にもとづく改訂。EaselJS次期バージョン候補(NEXT)にもとづいて、大幅に改定。「実装」のEventDispatcher.dispatchEvent()メソッドは除き、EventDispatcher.on()メソッドに替えた。CreateJSの新バージョンのリリースにともなう記述の変更およびリンク追加。Stage.handleEvent()メソッドの説明と実装を加えた。2013年2月7日「EaselJSのイベントリスナーにFunction.bind()メソッドを適用するとリスナー内から削除できない」へのリンク追加とそれにともなう若干の修正。