Overlayの移動を感知するイベント処理 - YahooUserInterface

コンテナの移動を感知するイベント

Panelを移動させたときのイベント処理をしたかったので、調べてみた。Yahoo.widget.PanelのAPI*1を見てみるとPanelの親クラスであるOverlayでコンテナの移動に関するイベントが定義されてることがわかった。

  • beforeMoveEvent
    • 動く直前に発生する
  • moveEvent
    • 動いた後に発生する

参考 YAHOO.widget.Overlay

リスナ(こっから試行錯誤)

イベントがあるってことは、どっかにリスナも用意さてれるはず。そう思ってリスナを探してみた。

最初に考えたのはYAHOO.util.Event.on()を使うこと。でもこれは多分間違ってた。次にmoveEventが定義されてるYAHOO.util.Overlayをみてみた。そしたらenforceConstraintsっていうメソッドがあった。これはmoveEventが発生したときのデフォルトのハンドラーらしい。Overlayが定義されてるcontainer.jsのソースコードを見てみると次のようにデフォルトのハンドラーを登録してた。

this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);

どうやらイベントに対して直接ハンドラを登録してるみたい。

イベント
   ↓
イベントリスナ
   ↓
イベントハンドラ

っていう風に処理されてるんだとおもってたけど、今回の奴はイベントから直接イベントハンドラを呼び出してるみたい。わざわざイベントリスナ作るのも面倒なので、同じ方法でイベントハンドラを登録した。


moveEventが発生したらアラートが出る例

this.moveEvent.subscribe( alert("move!") , this, true);

これと同じようにしてbeforeMoveにもハンドラを加えてみた。でもこっちは動かなかった。

this.beforeMoveEvent.subscribe( alert("before move!") , this, true);

なんでbeforeMoveは動かなかったのか考えてみた(正しいかどうかは分からない)

beforeMoveにはすでにデフォルトのハンドラであるenforceConstraintsが登録されてるはずである。このenforceConstraintsは上で紹介したように、イベントリスナを使わず、イベントに直接イベントハンドラを追加していた。多分これが原因で登録できなかったんだと思う。

考えてみるとイベントが発生した後に処理を行うっていう意味ではイベントリスナもイベントハンドラも同じもの。発生したイベントを賢く扱うためにイベントとイベントハンドラの間にイベントリスナが設けられるんだと思う。多分イベントリスナの機能として、発生したイベントに対して複数のハンドラを実行できるっていうのがある。今回イベントリスナを使わなかったので、moveEventにsubscribe出来なかったんだと思う。

余談 javascriptについて

javascriptの言語仕様がまだ良く分からない。Javaだとクラスとメソッドに明確な区別があるけど、javascriptにはそれが無いのかなって思った。メソッドだと思ってたのにクラスのように振舞ってる。本当に謎だ。