Custom Event

次のサンプルに行く前に、YUIのCustomイベントについて復習しておきたい(普通のclickとかkeyPressとかはDOMイベントと呼ばれる)。
どうも、MenuのCustom Eventのハンドルがうまく読めないからである。

次のサンプルである「Menu Family: Listening For Menu Events」にも、「MenuやMenuItemはCustom Event (YAHOO.util.CustomEvent)でインプリされているから、Custom Eventが説明されているページ(http://developer.yahoo.com/yui/event/index.html#customevent)を読め」と書いてある。

なので、そのページのサンプルを、もう一度、よく見てみようと思う。
このUsing the CustomEvent Objectの説明をコードに起して実行してみる。
この全文が以下で、実験のために若干修正を加え、注釈をつけてある。(ExampleのConsumerというオブジェクト名はわかりずらいので、Listnerに変更した)

<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE>Ajax_Sampling</TITLE>
<style type="text/css"> 
</style>
<!-- 読み込むscriptはyahoo-dom-event/yahoo-dom-event.jsだけ。 --> 
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js" ></script> 

<script>

//////////////////////////////////////////////////////////

// カスタムイベントを定義するオブジェクト(名前とCustomEventのインスタンスを持っている)
function TestObj(name) {
    this.name = name;
    // カスタムイベントのインスタンス化。
    // イベント名は、event1で、自身のインスタンス(this)をハンドラに送る。
    this.event1 = new YAHOO.util.CustomEvent("event1", this);
}

// カスタムイベントをListenし、Callbak(ハンドラ)を呼ぶオブジェクト
function Listner(name, testObj) {
    this.name = name;
    this.testObj = testObj;
    // testObj.event1をlistenする。ハンドラはonEvent1で、自身をコールバックの第3引数に渡す。
    this.testObj.event1.subscribe(this.onEvent1, this);
}

//Listnerにハンドラを定義する。
//第1引数は、イベントタイプ、第2引数はハンドラに送られる引数、第3はsubscribe時に
//指定される引数。(※)
Listner.prototype.onEvent1 = function(type, args, me) {
    alert(" this: " + this +
          "\n this.name: " + this.name +
          "\n type: " + type +
          "\n args[0].data: " + args[0].data +
          "\n me.name: " + me.name);
}

//////////////////////////////////////////////////////////

//適当なオブジェクトを用意する。
function TestData(data) {
    this.data = data;
}

// event1を定義したオブジェクトをインスタンス化。
var t1 = new TestObj("mytestobj1");
var t2 = new TestObj("mytestobj2");

// event1のリスナーをインスタンス化し、 
// インスタンス化したevent1を定義するオブジェクト(t1)を食わせる。
// このタイミングでevent1がサブスクライブされる。	
var c1 = new Listner("mytestconsumer1", t1);

// 適当なデータオブジェクトを作成(発火時の引数に使う)
var d1 = new TestData("mydata1");

// d1をパラメータにして、t1のevent1を発火すると、Listner内で発火がおこる。
// 発火したときのハンドラが、(この一文からでは)分からない。
// ただし、ハンドラには、(※)が返る。
t1.event1.fire(d1);

// t2はListnerに食わせてないので発火しない。
t2.event1.fire(d1);

</script>
</HEAD>

<BODY>
</body>
</HTML>

この結果の画面が以下である。

結果は、ページに示されている通りである。

何が知りたかったというと、ハンドラーに送られる「YUIのCustom Eventの使い方として標準的な戻り値」。
上の例では、

//第1引数は、イベントタイプ、第2引数はハンドラに送られる引数、第3はsubscribe時に
//指定される引数。(※)
Listner.prototype.onEvent1 = function(type, args, me) {・・・}

が示すように、

  1. イベントのタイプ
  2. 発火時にハンドラに送られる引数(オブジェクト);上の例をみるとなんでもいいことが分かる。
  3. subscribe時に渡される引数(常識的には、ハンドラースコープとなるsubscribeメソッドを持ったオブジェクトのインスタンス

のようだ。
Menu回りのハンドラーを見ている限り、このあたりがばらついているように感じる。
読み通しにくい(= Case by caseで覚えるしかない)と感じるのは、私だけなのかな。