この Tips集のようにブラウザを Frame で分割し、
左をメニュー・右をメインにした構成のページは結構多いと思われます。
この構成のページの場合、
メニューのリンクをクリックしてメインに本文を表示するが一般的ですが、
本文が似通った構成である場合には、
現在表示している本文がどのメニューで表示されているものかわからなくなることがあります。
この様な場合の改善策としては、
選択された項目がオープン状態のメニューを用意しておき、
選択された時に本文とメニュー(時には Frame も)を更新する方法があります。
この方法は複数のメニューを用意するので、
本文表示の際のセッション数が増えるデメリットがあります。
JavaScriptを利用した例としては、
選択中の本文を Frame の親ドキュメントに設定しておき、
メニュー表示時に JavaScript で全ての項目を表示する方法があります。
この例としては、この Tips集の「フォルダー型階層メニュー」がありますが、
項目をクリックする度にメニューの再表示を行なう必要があります。
ここで紹介する方法は、構成が変更されないメニューで、 項目がクリックされた場合に、選択項目の一部(イメージ)を変更することで、 現在表示中の本文をページの再表示なしに変更する方法です。
以下に、親ドキュメントを Frame.htm、メニューを Contents.htm、 本文を Doc.htm として、そのコードを示します。
Frame の親( Frame.htm )
<head> : <script language="JavaScript"><!-- curName = ''; // 現在表示中の項目名 loaded = false; // メニューのロード状態 // 表示中ドキュメント状態変更用中継関数 function chgImage(nm){ if (loaded) window.contents.openDoc(nm); else curName=nm; } // --></script> </head> <frameset cols="20%,*" border=0 frameborder=no framespacing=0> <frame name="contents" src="Contents.htm"> <frame name="doc" src="Doc.htm"> </frameset>
メニュー( Contents.htm )
<head> : <script language="JavaScript"><!-- // ダミー関数 function init(){} function activate(nm,dir){} function openDoc(nm){} // --></script> <script language="JavaScript1.1"><!-- activeName = ''; // 現在マウスが触れている項目 // アイコン画像の定義 unselectImage = 'UCLOSED.gif'; // マウスが触れていない場合 selectImage = 'CLOSED.gif'; // マウスが触れている場合 openImage = 'OPEN.gif'; // 本文が表示中の場合 // パフォーマンス対策用 unselectImg = new Image(); unselectImg.src=unselectImage; selectImg = new Image(); selectImg.src =selectImage; openImg = new Image(); openImg.src =openImage; // アイコン画像を変更する関数 function setImage(nm,imgno){ var img=unselectImg.src; if(imgno==1) img=selectImg.src; else if(imgno==2) img=openImg.src; eval('document.'+nm).src=img; } // 本文表示時のアイコン画像更新関数 function openDoc(nm){ if(parent.curName!='' && nm!=parent.curName){ if(activeName==parent.curName) setImage(parent.curName,1); else setImage(parent.curName,0); } parent.curName=nm; if(nm!='') setImage(parent.curName,2); } // メニュー用 HTML のローディング完了時の処理 function init(){ parent.loaded = true; if(parent.curName!='') openDoc(parent.curName); } // マウス移動時のアイコン画像更新関数 function activate(nm,dir){ if(nm!=activeName){ if(activeName!='' && activeName!=parent.curName) setImage(activeName,0); activeName=nm; } if(activeName == parent.curName) setImage(nm,2); else if(dir) setImage(nm,1); else setImage(nm,0); if(!dir) activeName=''; } // --></script> </head> <body ... onLoad="init();"> : <a href="Doc.htm" target="doc" onMouseOver="activate('Doc',true );" onMouseOut ="activate('Doc',false);" ><img name="Doc" src="UCLOSED.gif" border=0 >ドキュメント1</a> :
本文( Doc.htm )
<body ... onLoad="if(parent.chgImage) parent.chgImage('Doc');">
この文字の部分は必要に応じて修正します。
フレームの HTML では FRAMESET でページをレイアウトするとともに、
状態表示を行うフレーム( メニュー )の名称に
chgImage 関数の contents を変更します。
メニュー側では unselectImage, selectImage, openImage
変数で定義している画像を使用する画像に変更します。
※ これらの画像は全て同じサイズの画像にします。
状態表示を行う部分ではマウスが触れたとき表示変更するなら、
onMouseOver, onMouseOut イベントで activate 関数を呼び出します。
activate 関数の引数は以下の通りです。
※ アイコン画像は最初に unselectImg で定義した画像にします。
activate( nm, dir ) nm : 変更するアイコン画像に付けた名称( name属性 ) dir : 表示方向 true = selectImg で定義した画像を表示 false = unselectImg で定義した画像を表示
状態表示の対象となるドキュメント( 本文 )では BODY部の onLoad イベントで、
parent.chgImage 関数を呼び出します。
もし、本文がフレームの子としてではなく、単独で表示される可能性があるなら、
if(parent.chgImage) で判定しておくと良いでしょう。
chgImage の引数は以下の通りです。
chgImage( nm ) nm : 変更するアイコン画像に付けた名称( name属性 )
使用例
このコードの表示サンプルは こちら です。
注意事項
interval = 1000; // 監視間隔( msec ) tid = null; // タイマ識別子 function Mac4_5CacheBugFix(scr){ if( document.all && !document.getElementById && navigator.userAgent.indexOf('Mac')!=-1) tid = setTimeout(scr,interval); } function init(pageId){ if(parent.chgImage){ Mac4_5CacheBugFix('init("'+pageId+'")'); parent.chgImage(pageId); } } <body ... onLoad="init('Doc');">