Menu Family: Website Left Nav With Submenus From JavaScript

このサンプルは、先の「Menu Family: Website Left Nav With Submenus Built From Markup」をScriptを使って生成しようというもの(Exampleのページへのリンクはこちら)。

画面とその動きは、先の例とまったく同じである。

最後に示すhtml中のJavascriptを見れば明らかであるが、サブメニューの定義は、オブジェクト・リテラルで定義している(したがって、記述の手間や書き方という意味では、markupの時とさほど変わりがない)。
このオブジェクトリテラルの記述方法は、「Menu Family: Multi-tiered Menu From JavaScriptComments」で示した規則に則っている。

また、この例では、メニューのトップはmarkupを使って記述されている。
そして、YAHOO.widget.MenuのbeforeRenderイベントを使ってサブメニューを追加していくという戦術をとっている(YAHOO.widget.Menuのイベントについては、APIドキュメントを参照。これをみると、MENUオブジェクトの親の親となる。YAHOO.widget.Moduleから継承したイベントであることがわかる)。
beforeRenderイベントは、Menuのrenderの前処理として発火するので、renderメソッド以前にイベントハンドラを仕込む。

以下にJavasdcriptを含むHTMLの全体を示す。
ソースコードは、module patternで書き直した。

<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>
<!-- ヘッダー部、本文(コンテンツ部、メニュー部)、フッター部を分けるグリッド表示のCSS -->
<link rel="stylesheet" type="text/css" href="scripts/yui/reset-fonts-grids/reset-fonts-grids.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">

div.yui-b p {
    margin: 0 0 .5em 0;
    color: #999;
}
            
div.yui-b p strong {
    font-weight: bold;
    color: #000;
}
            
div.yui-b p em {
    color: #000;
}            

h1 {
   font-weight: bold;
   margin: 0 0 1em 0;
   padding: .25em .5em;
   background-color: #ccc;
}

#productsandservices {
   position: static;
}
/*
	For IE 6: trigger "haslayout" for the anchor elements in the root Menu by 
	setting the "zoom" property to 1.  This ensures that the selected state of 
	MenuItems doesn't get dropped when the user mouses off of the text node of 
	the anchor element that represents a MenuItem's text label.
*/

#productsandservices .yuimenuitemlabel {
	_zoom: 1;
}

#productsandservices .yuimenu .yuimenuitemlabel {
	_zoom: normal;
}
</style>

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

YAHOO.EGP.ScriptMenu = function() {

	var oMenu;
    var aSubmenuData = [
                        {
                            id: "communication", 
                            itemdata: [ 
                                { text: "360", url: "http://360.yahoo.com" },
                                { text: "Alerts", url: "http://alerts.yahoo.com" },
                                { text: "Avatars", url: "http://avatars.yahoo.com" },
                                { text: "Groups", url: "http://groups.yahoo.com " },
                                { text: "Internet Access", url: "http://promo.yahoo.com/broadband" },
                                {
                                    text: "PIM", 
                                    submenu: { 
                                                id: "pim", 
                                                itemdata: [
                                                    { text: "Yahoo! Mail", url: "http://mail.yahoo.com" },
                                                    { text: "Yahoo! Address Book", url: "http://addressbook.yahoo.com" },
                                                    { text: "Yahoo! Calendar",  url: "http://calendar.yahoo.com" },
                                                    { text: "Yahoo! Notepad", url: "http://notepad.yahoo.com" }
                                                ] 
                                            }
                                
                                }, 
                                { text: "Member Directory", url: "http://members.yahoo.com" },
                                { text: "Messenger", url: "http://messenger.yahoo.com" },
                                { text: "Mobile", url: "http://mobile.yahoo.com" },
                                { text: "Flickr Photo Sharing", url: "http://www.flickr.com" },
                            ]
                        },

                        {
                            id: "shopping", 
                            itemdata: [
                                { text: "Auctions", url: "http://auctions.shopping.yahoo.com" },
                                { text: "Autos", url: "http://autos.yahoo.com" },
                                { text: "Classifieds", url: "http://classifieds.yahoo.com" },
                                { text: "Flowers & Gifts", url: "http://shopping.yahoo.com/b:Flowers%20%26%20Gifts:20146735" },
                                { text: "Real Estate", url: "http://realestate.yahoo.com" },
                                { text: "Travel", url: "http://travel.yahoo.com" },
                                { text: "Wallet", url: "http://wallet.yahoo.com" },
                                { text: "Yellow Pages", url: "http://yp.yahoo.com" }                    
                            ]    
                        },
                        
                        {
                            id: "entertainment", 
                            itemdata: [
                                { text: "Fantasy Sports", url: "http://fantasysports.yahoo.com" },
                                { text: "Games", url: "http://games.yahoo.com" },
                                { text: "Kids", url: "http://www.yahooligans.com" },
                                { text: "Music", url: "http://music.yahoo.com" },
                                { text: "Movies", url: "http://movies.yahoo.com" },
                                { text: "Radio", url: "http://music.yahoo.com/launchcast" },
                                { text: "Travel", url: "http://travel.yahoo.com" },
                                { text: "TV", url: "http://tv.yahoo.com" }              
                            ] 
                        },
                        
                        {
                            id: "information",
                            itemdata: [
                                { text: "Downloads", url: "http://downloads.yahoo.com" },
                                { text: "Finance", url: "http://finance.yahoo.com" },
                                { text: "Health", url: "http://health.yahoo.com" },
                                { text: "Local", url: "http://local.yahoo.com" },
                                { text: "Maps & Directions", url: "http://maps.yahoo.com" },
                                { text: "My Yahoo!", url: "http://my.yahoo.com" },
                                { text: "News", url: "http://news.yahoo.com" },
                                { text: "Search", url: "http://search.yahoo.com" },
                                { text: "Small Business", url: "http://smallbusiness.yahoo.com" },
                                { text: "Weather", url: "http://weather.yahoo.com" }
                            ]
                        }                    
                    ];
    	
	
	return{
    	init: function() {
            /*
		    Menuのインスタンス化;第1引数はMenu部を意味するDivのid.
		          第2引数はCOnfigプロパティー。
	        */
           oMenu = new YAHOO.widget.Menu("productsandservices", 
					// Menuのコンフィグのためのオブジェクトリテラル
                   { 
                    // static Menuの表示。
                    position: "static", 
                    // Menuが消えるまでの時間(msec)
                    hidedelay:  750,
                    // 表示するときまで、レンダリングを待つ。
                    lazyload: true 
                    }
           );

           oMenu.subscribe("beforeRender", function () {
               // ここで取れるthisは、oMenu(発火するインスタンス)
               if (this.getRoot() == this) {

                   this.getItem(0).cfg.setProperty("submenu", aSubmenuData[0]);
                   this.getItem(1).cfg.setProperty("submenu", aSubmenuData[1]);
                   this.getItem(2).cfg.setProperty("submenu", aSubmenuData[2]);
                   this.getItem(3).cfg.setProperty("submenu", aSubmenuData[3]);
               }
           });

           // stataic Menu(CSSで規定されたメニュー)なので、renderだけで、
           // showはいらない
           oMenu.render();            
   		
		}
	};
}();

//DOMが完全にloadされたら、サンプルを初期化する。
YAHOO.util.Event.onDOMReady(
	//DomReadyイベントで発火するハンドラ
	YAHOO.EGP.ScriptMenu.init,
	//ハンドラに渡すオブジェクト(関数)
	YAHOO.EGP.ScriptMenu,
	//ハンドラは、上記のオブジェクトのスコープをもつ。   
	true
);

</script>
</HEAD>

<!-- class=" yui-skin-sam"の指定が必要 -->
<BODY class="yui-skin-sam">

<div id="doc" class="yui-t1">
    <div>
      <!-- start: your content here -->
	  <p>ここはヘッダーです。</p>
      <h1>Example: Website Left Nav With Submenus Built From Markup (YUI Library)</h1>
       <!-- end: your content here -->
    </div>
	
    <div id="bd">
       <!-- start: primary column from outer template -->
       <div id="yui-main">
         <div class="yui-b">
       		 <p>ここはコンテンツ(本文)です。</p>
             <p><strong>NOTE:</strong> <em>このExampleは、bidy内に記述されたマークアップから、
             			サブメニュー付のメニューを作る方法を説明しています。</em></p>
             <p>今日はいい天気だ。</p>
             <p>散歩でもしよう。</p>
           </div>
       </div>
       <!-- end: primary column from outer template -->

       <!-- start: secondary column from outer template -->

       <!-- メニュー部 「ajax_yui_menu_multi_tier_from_markup.html」と同じ-->
       <div class="yui-b">

          <div id="productsandservices">
              <div class="bd">
                 <ul>
                     <li class="yuimenuitem"><a href="#communication">Communication</a>
                     </li>
                     <li class="yuimenuitem"><a href="http://shopping.yahoo.com">Shopping</a>
                     </li>
                     <li class="yuimenuitem"><a href="http://entertainment.yahoo.com">Entertainment</a>
                     </li>
                     <li class="yuimenuitem"><a class="yuimenuitemlabel" href="#">Information</a>                      
                     </li>
                   </ul>            
             </div>
         </div>
      </div>
    </div>

    <!-- footer部 -->
    <div>
       <p>ここはフッターです。</p>
    </div>
</div>

</BODY>
</HTML>