Browser History Manager: TabView Control
YUIには、Browser History Managerという変わった機能がある。
このサンプルは以下のようにTabviewを使った例となっている。
ここで、上の画面には現れていないが、ブラウザーのURLが
http://........../ajax_yui_history_tabview_control.html#tabview=tab1
となっている。
History Managerでは、このように(セクションを表示する形式で)画面の遷移が管理される。History Managerがユニークなのは、画面の「進む」/「戻る」という動きについても、これをスタックするようになっていること。
そして、これらの管理された画面の動きは、「進む」/「戻る」ボタンと連動したHistory Managerから再現される。
History Managerは、画面の遷移をスタックするもので、画面そのものをキャッシュするものではない。
(ブラウザのキャッシュ機能が有効になっていれば、staticなページについてはそれが再利用される。History Mangerによって遷移がスタックされ、ブラウザーの機能によってキャッシュされることになる)
以下にHTMLの全文を示す。
YUIのExampleのソースは非常に読みにくいので、モジュールパターンで書き直しを行い、どのような手順でHistory Managerが画面をスタックしていくのかについて注釈を加えた(特に重要な部分については、[戦略]という書いてある)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Ajax Sample</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/tabview/assets/skins/sam/tabview.css" /> <script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="scripts/yui/element/element-beta-min.js"></script> <script type="text/javascript" src="scripts/yui/tabview/tabview-min.js"></script> <script type="text/javascript" src="scripts/yui/history/history-min.js"></script> <style type="text/css" id="defaultstyle"> #main { margin: 2px; padding: 3px; width: 450px; } #yui-history-iframe { position:absolute; top:0; left:0; width:1px; height:1px; /* avoid scrollbars */ visibility:hidden; } #demo { margin-bottom:1em; } </style> <script type="text/javascript"> // //モジュールパターンで実装する。 // YAHOO.namespace("EGP"); YAHOO.EGP.SimpleNavigation = function() { var bookmarkedTabViewState; var initialTabViewState; var tabView; // Activeなタブが変更されたら実行されるハンドラ。 // ... [戦略] タブ変更のイベントで、訪れたstate(ページ)をnavigateでスタックし、 // register時に登録した、※1様の、ページ表示関数を呼び出す。 function handleTabViewActiveTabChange (e) { var newState, currentState; newState = "tab" + this.getTabIndex(e.newValue); try { currentState = YAHOO.util.History.getCurrentState("tabview"); if (newState != currentState) { // 訪れたstateをスタックする。そして、※1を呼ぶ。 YAHOO.util.History.navigate("tabview", newState); } } catch (e) { tabView.set("activeIndex", newState.substr(3)); } } // Tabviewの初期化を行う。 // ... [戦略] ※2 画面を表示させるための初期化処理を行い、※3様のハンドラを仕掛ける。 function initTabView () { // Instantiate the TabView control... tabView = new YAHOO.widget.TabView("demo"); // [戦略] ※3 ページが遷移するイベントに、上のようなハンドラを仕掛ける。 tabView.addListener("activeTabChange", handleTabViewActiveTabChange); } return { init : function(){ // 初期画面(initSection)の決定を行う。========================== // 決まり文句 bookmarkedTabViewState = YAHOO.util.History.getBookmarkedState("tabview"); initialTabViewState = bookmarkedTabViewState || "tab0"; // モジュール;navbar(これがSection名になる)とその最初のセクションを登録する。=================== // (注) History.initializeより前に行われなくていけない。 YAHOO.util.History.register("tabview", initialTabViewState, // [戦略] ※1 // この関数は、YAHOO.util.History.navigateが呼ばれるか、back/forward button // が押されたときに動く。 function (state) { // tabviewのタブを変更 tabView.set("activeIndex", state.substr(3)); } ); // History Managerがreadyになったら発火するハンドラ。===================== // ...History Managerが非同期に生成されるため。 YAHOO.util.History.onReady(function () { var currentState; initTabView(); // currestState(tab0 etc)が入る。 currentState = YAHOO.util.History.getCurrentState("tabview"); tabView.set("activeIndex", currentState.substr(3)); }); // History Managerの初期化========================================== // initialize("aplicationのステートを保存するマークアップ","Historyを保存するiframe") try { YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe"); } catch (e) { // The only exception that gets thrown here is when the browser is // not supported (Opera, or not A-grade) Degrade gracefully. initTabView(); } } }; }(); //DOMが完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.SimpleNavigation.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.SimpleNavigation, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); </script> </head> <body class="yui-skin-sam"> <iframe id="yui-history-iframe" src="scripts/yui/history/assets/blank.html"></iframe> <input id="yui-history-field" type="hidden"> <div id="main"> <div id="demo" class="yui-navset yui-navset-top"> <ul class="yui-nav"> <li> <a href="#tab1"><em>Tab One Label</em></a> </li> <li title="active" class="selected"> <a href="#tab2"><em>Tab Two Label</em></a> </li> <li title="" class=""> <a href="#tab3"><em>Tab Three Label</em></a> </li> </ul> <div class="yui-content"> <div style="display: none;" id="tab1"><p>Tab One Content</p></div> <div style="display: block;" id="tab2"><p>Tab Two Content</p></div> <div style="display: none;" id="tab3"><p>Tab Three Content</p></div> </div> </div> </div> </body> </html>