基本のHTMLとCSSの設定

ツリービューといえばやはり開くボタンをクリックすると、子が表示されたり隠れたりが醍醐味ですね。それらの動きはブラウザなのでJavascriptで動かします。でもJavaScriptも基本となるHTMLの構造がなっていないと、作りようもないですね。まずはツリービューのHTML構造です。

項目

ポイント

評価

項目

テーブル構造

ポイント

HTML構造が複雑

評価

×

項目

リスト構造

ポイント

HTML構造がシンプル、list-style-imageスタイルが便利

評価

項目

DIV構造

ポイント

HTML構造がシンプル

評価

ツリービューのHTML構造として主に、"テーブル構造","リスト構造","DIV構造"があります。私は主にリスト構造のタイプを使用しています。テーブル構造だと複雑すぎるのとHTMLがゴチャゴチャになりがちなので却下。DIV構造でもよかったのですが、リスト構造のlist-style-imageのスタイルで簡単に展開ボタンを指定できるので楽に作る事ができるからです。

HTML

<ul id="TreeView1" onclick="ClickEvent();">
  <li class="reaf collapse expand">
    <span>Node1</span>
    <ul>
      <li class="reaf collapse expand">
        <span>Node1-1</span>
        <ul>
          <li class="reaf">
            <span>Node1-1-1</span>
            <ul></ul>
          </li>
          <li class="reaf">
            <span>Node1-1-2</span>
            <ul></ul>
          </li>
        </ul>
      </li>
      <li class="reaf collapse">
        <span>Node1-2</span>
        <ul>
          <li class="reaf">
            <span>Node1-2-1</span>
            <ul></ul>
          </li>
          <li class="reaf">
            <span>Node1-2-2</span>
            <ul></ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

クラス名付与時のルールとしては、ツリービューのアイテムに"reaf"、子要素があるものには"collapse"を追加、更に子要素を展開する場合は"expand"を追加します。

CSS

  ul {
   margin: 0;
   margin-left: 0.5em;
   padding: 0 0 0 0;
  }

  li {
   margin-left: 0.5em;
   list-style-position: outside;
   list-style-type: none;
   font-size: 13pt;
  }

   li.reaf {
    list-style-image: url(ファイルパス);
    cursor: pointer;
   }

   li.collapse {
    list-style-image: url(ファイルパス);
   }

   li.expand {
    list-style-image: url(ファイルパス);
   }

   li.reaf > li, li.collapse > ul {
    display: none;
   }

   li.expand > ul {
    display: block;
   }

CSSのルールで下に書いたものが優先的にスタイルが適用されます。なので"reaf","collapse","expand"のクラスはこの順序で記載する必要があります。

JavaScript

function ClickEvent() {
  var sender = event.srcElement || event.target;
  if (sender.nodeName == "LI") {
    var clist = sender.classList;
    if (clist.contains("collapse")) {
      clist.toggle("expand");
    }
  }
}

比較的新しいブラウザだと採用されている"classList"を使用すると、ポンポンクラスを追加するだけで実装できてしまうので楽ですね。


JavaScriptでTreeViewを作成する

でもいちいちHTMLを変更するのって面倒ですよね。JavaScriptに記載したオブジェクトの構造通りにTreeViewを作成する方法です。今までの内容に以下のスクリプトを追加します。

JavaScript

//ツリービューのデータ
var tvObj = {
  id:"treeview1",Nodes:[
    {
      label: "Node1", Nodes: [
        {label: "Node1-1" },
        {label: "Node1-2",
         Nodes: [
          {label:"Node1-2-1"}
         ]
        }
      ]
    },
    {label:"Node2"}
  ]
};

function LoadEvent() {
  var target = document.getElementById(tvObj.id);
  target.onclick = ClickEvent; //ツリービューにイベントの登録
  var catcherNode = target.lastChild;
  for (var n in tvObj.Nodes) {
    var newTreeViewItem = CreateTreeViewItem(tvObj.Nodes[n].label);
    target.appendChild(newTreeViewItem);
    AddTreeViewItem(tvObj.Nodes[n], newTreeViewItem);
  }
}

function AddTreeViewItem(tvObj, rootNode) {
  var clsList = rootNode.classList;
  var target = rootNode.lastChild;
  for (var n in tvObj.Nodes) {
    if (clsList.contains("collapse") == false) {
      clsList.add("collapse");
    }
    var newTreeViewItem = CreateTreeViewItem(tvObj.Nodes[n].label);
    target.appendChild(newTreeViewItem);
    AddTreeViewItem(tvObj.Nodes[n], newTreeViewItem);//末端の子要素まで追加したいので再起処理
  }
}

function CreateTreeViewItem(labelTxt) {
  var ret = document.createElement("li");
  ret.className = "reaf";
  var labelNode = document.createElement("span");
  labelNode.innerHTML = labelTxt;
  ret.appendChild(labelNode);
  ret.appendChild(document.createElement("ul"));
  return ret;
}

ここまで来たらもう簡単ですね。ブラウザ間の処理を加えていくだけです。テストはIEでのみ実施しています。W3C対応のブラウザは個々の仕様に合わせて修正する必要があります。