Menu Family: Website Top Nav Using Animation With Submenus From JavaScript
このExampleは、先の「Menu Family: Website Top Nav Using Animation With Submenus Built From Markup」のサンプルをScriptで記述したものである。(YUIのExampleページへのリンクはこちら)
したがって、画面とその動作は、「Menu Family: Website Top Nav Using Animation With Submenus Built From Markup」のサンプルとまったく変わりがない。
また、MarkupからScriptへのコードの変更は、「Menu Family: Website Top Nav With Submenus Built From Markup」から「Menu Family: Website Top Nav With Submenus From JavaScript」への変更とまったく同じ方法をとっている。
先の「Menu Family: Website Top Nav Using Animation With Submenus Built From Markup」のサンプルは、(UserAgentごとの調整など)面倒なコードを含んでいたが、MarkupからScriptに変更することでも、このあたりの改善はなされないようである。
また、画面にトレースされるログにも変わりがない。
以下のJavascriptを含む、htmlの全体を示す。
<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" /> --> <!-- ヘッダー部、本文(コンテンツ部、メニュー部)、フッター部を分けるグリッド表示の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> <script type="text/javascript" src="scripts/yui/animation/animation.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; } /* メニューのbottom marginを設定 */ #productsandservices { margin: 0 0 10px 0; } </style> <script type="text/javascript"> //モジュールパターンで実装する。 YAHOO.namespace("EGP"); YAHOO.EGP.MarkupMenu = function() { var oMenu; var ua = YAHOO.env.ua, oAnim; // Animation instance Dom = YAHOO.util.Dom; 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" } ] } ]; /* SubMenuが開く前のイベントのハンドラ; thisは<ul>エレメント。 サブメニューがAnimationされる前のスタイルの調整を行う。 <ul>エレメント(サブメニュー)のアニメーションを動かす。 */ var onSubmenuBeforeShow = function (p_sType, p_sArgs) { var oBody, oElement, oShadow, oUL; //ログの表示 if(this instanceof YAHOO.widget.MenuBarItem){ var nInst = 'YAHOO.widget.MenuBarItem'; } else if(this instanceof YAHOO.widget.MenuItem){ nInst = 'YAHOO.widget.MenuItem'; } else { nInst = 'unknown'; } var log = '<hr/><font color="red"> owner: ' + this.cfg.toString() + ' instance of :' + nInst + ' (in onSubmenuBeforeShow) ' + '</font><br/>'; Dom.get('log').innerHTML += log; if (this.parent) { // subメニュー(ul以下のDOM)の保管 oElement = this.element; /* Get a reference to the Menu's shadow element and set its "height" property to "0px" to syncronize it with the height of the Menu instance. */ // これで陰影が取得できる?? oShadow = oElement.lastChild; // 陰影を隠す。 oShadow.style.height = "0px"; /* Stop the Animation instance if it is currently animating a Menu. */ if (oAnim && oAnim.isAnimated()) { oAnim.stop(); oAnim = null; } /* Set the body element's "overflow" property to "hidden" to clip the display of its negatively positioned <ul> element. */ // class="bd" を保存 oBody = this.body; // Check if the menu is a submenu of a submenu. // Submenu の SubMenuの時の処理(User Agentのごとの調整) if (this.parent && !(this.parent instanceof YAHOO.widget.MenuBarItem)) { /* There is a bug in gecko-based browsers and Opera where an element whose "position" property is set to "absolute" and "overflow" property is set to "hidden" will not render at the correct width when its offsetParent's "position" property is also set to "absolute." It is possible to work around this bug by specifying a value for the width property in addition to overflow. */ if (ua.gecko || ua.opera) { oBody.style.width = oBody.clientWidth + "px"; } /* Set a width on the submenu to prevent its width from growing when the animation is complete. */ if (ua.ie == 7) { oElement.style.width = oElement.clientWidth + "px"; } } // class="bd" のスタイル oBody.style.overflow = "hidden"; /* Set the <ul> element's "marginTop" property to a negative value so that the Menu's height collapses. */ // class="bd" 内のulをとる。 oUL = oBody.getElementsByTagName("ul")[0]; // marginTopをマイナスにしてサブメニューを隠してしまう。(※) oUL.style.marginTop = ("-" + oUL.offsetHeight + "px"); } } /* Anmationの間の処理; ieのときしか動かない。 */ var onTween = function (p_sType, p_aArgs, p_oShadow) { //ログの表示 if(this instanceof YAHOO.widget.MenuBarItem){ var nInst = 'YAHOO.widget.MenuBarItem'; } else if(this instanceof YAHOO.widget.MenuItem){ nInst = 'YAHOO.widget.MenuItem'; } else { nInst = 'unknown'; } var log = '<hr/><font color="blue"> owner: ' + this.cfg.toString() + ' instance of :' + nInst + ' (in onTween) ' + '</font><br/>'; Dom.get('log').innerHTML += log; if (this.cfg.getProperty("iframe")) { this.syncIframe(); } if (p_oShadow) { p_oShadow.style.height = this.element.offsetHeight + "px"; } } /* SubMenuが開くときのイベントのハンドラ; thisは<ul>エレメント。 <ul>エレメント(サブメニュー)のアニメーションを動かす。 */ var onSubmenuShow = function (p_sType, p_sArgs) { var oElement, oShadow, oUL; var obj = this; //ログの表示 if(obj instanceof YAHOO.widget.MenuBarItem){ var nInst = 'YAHOO.widget.MenuBarItem'; } else if(obj instanceof YAHOO.widget.MenuItem){ nInst = 'YAHOO.widget.MenuItem'; } else { nInst = 'unknown'; } obj = this.parent; if(obj instanceof YAHOO.widget.MenuBarItem){ var pInst = 'YAHOO.widget.MenuBarItem'; } else if(obj instanceof YAHOO.widget.MenuItem){ pInst = 'YAHOO.widget.MenuItem'; } else { pInst = 'unknown'; } var log = '<hr/> owner: ' + this.cfg.toString() + ' instance of :' + nInst + ' instance(parent) of :' + pInst + ' (in onSubmenuShow) ' + '<br/>'; Dom.get('log').innerHTML += log; if (this.parent) { oElement = this.element; oShadow = oElement.lastChild; // class=bdの取得。 oUL = this.body.getElementsByTagName("ul")[0]; // marginTopをマイナスにして隠してしまったもの0に戻すことで、現れる。 oAnim = new YAHOO.util.Anim(oUL, { marginTop: { to: 0 } }, .5, YAHOO.util.Easing.easeOut); // フレームの陰影の高さを100%にする。 oAnim.onStart.subscribe(function () { oShadow.style.height = "100%"; }); oAnim.animate(); /* Subscribe to the Anim instance's "tween" event for IE to syncronize the size and position of a submenu's shadow and iframe shim (if it exists) with its changing height. */ if (YAHOO.env.ua.ie) { oShadow.style.height = oElement.offsetHeight + "px"; /* Subscribe to the Anim instance's "tween" event, passing a reference Menu's shadow element and making the scope of the event listener the Menu instance. */ oAnim.onTween.subscribe(onTween, oShadow, this); } /* Subscribe to the Anim instance's "complete" event, passing a reference Menu's shadow element and making the scope of the event listener the Menu instance. */ oAnim.onComplete.subscribe(onAnimationComplete, oShadow, this); } } return{ init: function() { /* Menuのインスタンス化;第1引数はMenu部を意味するDivのid. 第2引数はConfigプロパティー。 */ oMenuBar = new YAHOO.widget.MenuBar("productsandservices", // Menuのコンフィグのためのオブジェクトリテラル { // MouseOverでsubmenuが展開される。 autosubmenudisplay: true, // Menuが消えるまでの時間(msec) hidedelay: 750, // 表示するときまで、レンダリングを待つ。 lazyload: true } ); oMenuBar.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]); } }); // subMenuが開く直前に発火 oMenuBar.subscribe("beforeShow", onSubmenuBeforeShow); // subMenuが開く際に発火 oMenuBar.subscribe("show", onSubmenuShow); //renderだけで、showはいらない oMenuBar.render(); } }; }(); //DOMが完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.MarkupMenu.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.MarkupMenu, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); </script> </HEAD> <body class="yui-skin-sam"> <div id="doc" class="yui-t1"> <div> <!-- start: your content here --> <p>ヘッダー:ここがヘッダーです。</p> <h1>Example: Website Top Nav Using Animation With Submenus From JavaScript (YUI Library)</h1> <!-- end: your content here --> </div> <div id="bd"> <div id="yui-main"> <!-- 1コラム目のスタート(メニューバー、とコンテンツ) --> <div class="yui-b"> <!-- start: stack grids here --> <!-- メニュー部 --> <div id="productsandservices" class="yuimenubar yuimenubarnav"> <div class="bd"> <ul> <li class="yuimenubaritem"><a href="#communication">Communication</a> </li> <li class="yuimenubaritem"><a href="http://shopping.yahoo.com">Shopping</a> </li> <li class="yuimenubaritem"><a href="http://entertainment.yahoo.com">Entertainment</a> </li> <li class="yuimenubaritem"><a href="#">Information</a> </li> </ul> </div> </div> <!-- コンテンツ部 --> <p id="note"><strong>NOTE:</strong> <em>This example demonstrates how to add animation effects to a menu bar with submenus built using JavaScript.</em></p> <form name="example"> <select name="test"> <option value="one">One</option> <option value="two">Two</option> <option value="three">Three</option> </select> </form> <p>ここにログを出しちゃおう。</p> <div id='log'></div> <!-- end: stack grids here --> </div> </div> <!-- 1コラム目の終わり --> <!-- 2コラム目 --> <div class="yui-b"> <p>左ペインです。</p> </div> <!-- 2コラム目の終わり --> </div> <div> <p>フッター:ここがフッターです。</p> </div> </div> </body>