Listening For Menu Events

このExampleは、MenuインスタンスとMenuItemインスタンスイベントハンドラを設定し、ハンドラがイベントからの戻り値から情報を取り出すというもの(Exampleのページへのリンクはこちら)。

先のログ「Custom Event」でも述べたが、Custom Eventで実装されていると書かれている「イベントからの戻り値」に、どうも統一感がないように思われてならない。

とりあえず、動くサンプルを作成したので、以下に紹介しておく。

まず、初期画面は以下。

ここで、「メニューを紹介」ボタンを押すと、以下のような画面が現れる。ここまでは、YUIのExampleと同じ動きである。

YUIのExampleでは、イベントハンドラで取り出した情報をlogに書き出しているが、YAHOOのLoggerはまだ見ていないので、手っ取り早く、画面に書き出すようにしたのが、以下の画面である。
赤がMenuのイベントハンドラからの出力、黒がMenuItemのハンドラからの出力である。

以下にソースコードの全文を示す。
itemAddedイベント(Menuインスタンス)、Menu、MenuItemインスタンスに対するDOMイベントのハンドラの3種が使用されているが、いずれも、引数が異なっている(共通するのは、第1引数がイベントタイプであるということだけ)。
覚えてしまえば、それでいいのだが、なんとなく気持ちがわるい。

<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Ajax_Sampling</TITLE>
<style type="text/css">
body {
	margin:0;
	padding:0;
}
</style>
<link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/menu/assets/skins/sam/menu.css" />
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="scripts/yui/container/container_core-min.js"></script>
<script type="text/javascript" src="scripts/yui/menu/menu-min.js"></script>

<style type="text/css" id="defaultstyle">
#container {
	margin: 2px;
	padding: 3px;
	width: 400px;
	height: auto;
	border:1px dashed #999999;
}
div.yuimenu a.yuimenuitemlabel-disabled:visited {
    color: #A6A6A6;
}


</style>
<script type="text/javascript">
//モジュールパターンで実装する。
YAHOO.namespace("EGP");

YAHOO.EGP.ScriptMenu = function() {

	var oMenu;
		Dom = YAHOO.util.Dom;
	
	// 第1引数はCustomイベントの種類、第2引数はDOMイベントの種類
	// thisはMenuインスタンス
	var onMenuEvent = function (p_sType, p_aArgs) {
        
        var oDOMEvent = p_aArgs[0];
        var log = 	'<hr/><font color="red"> Id: ' + this.id + ', ' +
        			'Custom Event Type: ' + p_sType + ', ' +
        			'DOM Event Type: ' + oDOMEvent.type + '</font><br/>';
		Dom.get('log').innerHTML += log;

	};

	// 第1引数はCustomイベントの種類、第2引数はDOMイベントの種類
	// thisはMenuItemインスタンス
	var onMenuItemEvent = function (p_sType, p_aArgs) {

        var oDOMEvent = p_aArgs[0];
        var log = 	"Index: " + this.index + ", " +
        			"Group Index: " + this.groupIndex + ", " +
					"Custom Event Type: " + p_sType + ", " +
					"DOM Event Type: " + oDOMEvent.type + "<br/>";
		Dom.get('log').innerHTML += log;
    };

	return{

		init: function() {
		   // Muneのインスタンス生成
		   // コンストラクタの第1引数は、menuを構成するdivのid(この場合ない)、
		   // 第2引数は、属性を表すオブジェクトリテラル
		   // 属性はMenuのAPIドキュメント
		   // http://developer.yahoo.com/yui/docs/YAHOO.widget.Menu.html
   		
	   		oMenu = new YAHOO.widget.Menu("basicmenu", 
   			   				{ xy: [300,65] }
			);

			// MenuのitemAddedイベントで発火(MenuItem一つずつ発火する模様)。
			// 追加したMenuItemをp_aArgsで受け取って、イベントハンドラを仕掛ける。
			// イベントハンドラの第2引数には、発生させたMenuItemインスタンスがはいる。
			oMenu.subscribe("itemAdded", 
	    	   	function (p_sType, p_aArgs) {
	            	var oMenuItem = p_aArgs[0];

					// MenuItemにDOMイベントハンドラーを仕掛ける。
	            	oMenuItem.subscribe("mouseover", onMenuItemEvent);
	            	oMenuItem.subscribe("mouseout", onMenuItemEvent);
	            	oMenuItem.subscribe("mousedown", onMenuItemEvent);
	            	oMenuItem.subscribe("mouseup", onMenuItemEvent);
	            	oMenuItem.subscribe("click", onMenuItemEvent);
	            	oMenuItem.subscribe("keydown", onMenuItemEvent);
	            	oMenuItem.subscribe("keyup", onMenuItemEvent);
	            	oMenuItem.subscribe("keypress", onMenuItemEvent);
	        	}
        	);

	        // MenuインスタンスそのものにもDOMイベントのハンドラーを仕掛ける。
	        // MenuItemのイベントより先に発火する。
	        oMenu.subscribe("mouseover", onMenuEvent);
	        oMenu.subscribe("mouseout", onMenuEvent);
	        oMenu.subscribe("mousedown", onMenuEvent);
	        oMenu.subscribe("mouseup", onMenuEvent);
	        oMenu.subscribe("click", onMenuEvent);
	        oMenu.subscribe("keydown", onMenuEvent);
	        oMenu.subscribe("keyup", onMenuEvent);
	        oMenu.subscribe("keypress", onMenuEvent);

	        oMenu.addItems([
	                "MenuItem 0",
	                "MenuItem 1",
					// Menu2はdisabledにする。
	                { text: "MenuItem 2", disabled: true },
	                "MenuItem 3",
	                "MenuItem 4"
            ]);
	   		
			// 引数はrenderingしたメニューのターゲット
   			oMenu.render("rendertarget");

			// Bottunのクリックイベントにメニューの表示(show)を仕掛ける。
			// EventのAPIはhttp://developer.yahoo.com/yui/docs/YAHOO.util.Event.html
			// 第4引数は、ハンドラーへの引数、第5引数は実行scope.
   			YAHOO.util.Event.addListener(
   		   				"menubutton", 
   		   				"click", 
   		   				oMenu.show, 
   		   				null, 
   		   				oMenu
   		   	);
		}
	};
}();

//DOMが完全にloadされたら、サンプルを初期化する。
YAHOO.util.Event.onDOMReady(
		YAHOO.EGP.ScriptMenu.init
);

</script>
</HEAD>

<!-- class=" yui-skin-sam"の指定が必要 -->
<BODY class="yui-skin-sam">
<div id="container">
<p>
MenuとMenuItemにイベントハンドラを仕掛けます。<br/>
メニュー内外でのクリックにより、メニューが消えます。<br>
</p>
<button id="menubutton" type="button">Menuを表示</button>
<div id="rendertarget"></div>
<div id="log"></div>
</div>
</BODY>
</HTML>