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>