フォルダ型階層メニュー

iconfolder1
iconfolder3

解説

これはスタイルの制御を利用した階層メニューです
folder1 〜 folder3の文字またはアイコンをクリックすると 下のリンク部分の表示・非表示が切り替わります

■JavaScript
この文字はカスタマイズ項目です

// クラス名の定義
subpane_class = 'sub_pane'; // 折りたたみ領域
folder_class  = 'folder';   // フォルダ
icon_class    = 'icon';     // フォルダアイコン
// アイコンの定義
imgs = new Array(
  'OPEN.gif',               // 開いている状態
  'CLOSED.gif'              // 閉じている状態
);
// display スタイルの定義
displays = new Array(
  'block',                  // 開いている状態
  'none'                    // 閉じている状態
);

// フォルダ状態を逆転する関数
function menu_toggle(folder,icon){
  // DOM チェック
  if(!document.hasChildNodes) return;

  var node = null, state = folder.folder_state?1:0;
  var new_state = state?0:1;
  // アイコンの変更
  if(icon){
    if(icon.className && icon.className == icon_class)
      node = icon;
    else if(icon.hasChildNodes()){
      var nodes = icon.childNodes;
      for(var i=0; i<nodes.length; i++){
        var n = nodes[i];
        if(n.className && n.className == icon_class){
          node = n;
          break;
        }
      }
    }
    if(node) node.src = imgs[new_state];
  }
  // メニュー表示の変更
  if(folder.parentNode.hasChildNodes()){
    var nodes = folder.parentNode.childNodes;
    for(var i=0; i<nodes.length; i++){
      var node = nodes[i];
      if(node.className){
        if(node.className == subpane_class){
          node.style.display = displays[new_state];
          break;
        }
      }
    }
    folder.folder_state = new_state;
  }
  return false;
}

このスクリプトは以下の構成の HTML を前提としています

■前提とする HTML要素

<div class="pane">
  <span class="folder">
    <img class="icon" src="...">フォルダ
  </span>
  <div class="sub_pane">
  <a href="link1.htm">link1</a><br>
     :
  </div>
</div>

つまり、1つの制御単位 "pane" クラスの子として、 1つの "folder" クラス要素、1つの "sub_pane" クラス要素があり、 "folder" クラス要素には アイコン用クラス "icon" の画像( IMGタグ )が、 "sub_pane" クラス要素には折りたたむ対象のメニュー項目があります

menu_toggle 関数は第一引数として "folder" クラスの要素を、 第二引数として "icon" クラスまたは "icon" クラスの親の要素 または null を指定し、 呼び出すと "folder" クラスの兄弟要素にある "sub_pane" クラスの display 属性を切り替えるとともに 第二引数で指定した要素またはその子にある "icon" クラスの src属性を切り替えます

このルールを守る限りメニューのレイアウトは自由に指定できます

具体的にはこんな風に記述します

■HTML要素(例)

<div class="pane">
  <span class="folder"
        onclick="return menu_toggle(this,this);">
    <img src="OPEN.gif" class="icon">folder1</span>
  <div class="sub_pane">
  <a href="content1_1.html">link1</a><br>
  <a href="content1_2.html">link2</a><br>
     :
  </div>
</div>

複数のフォルダがあるなら、単に羅列すれば良く、 複数の階層が必要なら "sub_pane" 内に入れ子で記述すればOKです

注意とヒント

●このスクリプトは IE5.5, IE6, Mozilla1.4, Opera7.03( 以上 Windows ), Safari1.0, IE5.2( 以上 Mac 10.2 ), Konqueror3.1, Opera7.20 Beta7( 以上 RedHat 9 ) で確認しています
これより古いバージョンのブラウザでは正常に動作しないかもしれません

●Konqueror では 同一フォルダのクリック動作で1回おきにしか menu_toggle関数が呼び出されないバグがあります

●旧ブラウザでフォルダの選択動作を無効にする最も簡単な手法は onclickの指定を リンク( href付き Aタグ )ではなくアンカータグ( hrefなし A タグ )や span, imgタグに指定する方法でしょう

●旧ブラウザや JavaScript オフのブラウザを考慮すると メニューの初期表示は全て展開した状態で表示させた方が良いと思われます
( もちろん、onload で全てを閉じるスクリプトを追加するのはアリです f(^^; )

●どうしても初期表示の状態を折り畳んだ状態にしたい場合は "sub_pane" クラスの display 属性を "none" にして、 imgs, displays の配列要素の順番を逆にします

● "sub_pane" がブロック要素でない場合、displays 配列の定義の修正が必要です

●多階層のメニューで階層毎にスタイルの指定を変えたい場合は、 menu_toggle 関数に "sub_pane" のクラス名を引数に追加する修正をすれば良いと思います