SITEMAP [初めてのホームページ講座] [JavaScript , DHTML] [エクスプローラ風2段ツリー]

Dynamic HTMLの参考書 Java Scriptの参考書

エクスプローラ風2段ツリー

機能

WindowsのExplorer風のツリー形式での展開が可能なスクリプトです。 世の中にある一般的なものと機能は殆ど変わらないのですが、2段まで展開が可能な構成をとっています。 (逆に1段が出来ない・・・改良が必要)

当然クロスブラウズしていますので、IEでもNNでも対応可能です。 また、CSSによるスタイル指定によりきめ細かな設定が可能です。 その他、メニュー同士の隙間を任意に変更可能です。

類似サンプル

  1. エクスプローラ風無限ツリー

利用方法

HEAD部分にスタイルとスクリプトを記述します。 メニュー内のスタイルもここに記述します。

A要素にHREF属性でリンク先を「JavaScript:void(0)」にします。 この他にも、mouseovereのイベントハンドラを設定しますが、JavaScriptの関数「Mover(x,y)」を指定します。 ただし、x,yは指定したid属性名に規則的に合わせます。詳細は下記参照。 この他、メニュー数(Main,Sub)やレイヤーの座標などの指定も必要です。

メインメニュー
メインメニューは初期に全て表示します。このメニューの下にサブメニューを配置し、 そのサブメニューの下にコンテンツを配置します。メインメニューの表示内容はHTMLで記述します。 BODY要素内のDIV要素に記述しており、いずれもid属性が「iLx0」(xの部分は1からの連番)となっています。 プラスやマイナスのマークを画像で処理しており、これに該当するIMG要素も必要です。
サブメニュー
サブメニューは初期に全て非表示です。各メインメニューの下にそれぞれ存在し、このメニューの下にコンテンツを配置します。 サブメニューの表示内容はHTMLで記述します。 BODY要素内のDIV要素に記述しており、いずれもid属性が「iLxy」(x,yの部分は1からの連番)となっています。 プラスやマイナスのマークを画像で処理しており、これに該当するIMG要素も必要です。
コンテンツ
コンテンツは初期に全て非表示です。各サブメニューの下にそれぞれ1つずつ存在します。 この下にはメニューは存在しません。 コンテンツの表示内容はHTMLで記述します。 BODY要素内のDIV要素に記述しており、いずれもid属性が「iLcxy」(x,yの部分は1からの連番)となっています。

改造方法

メニューの数を自由に変更可能です。その際、スクリプトを一部変更する必要があります。 また、スタイルは比較的簡単に設定可能です。(CSSの知識が必要) この他、メニューの項目の隙間を変更することもできます。 配列構造とメニューとの関係は画像をご覧下さい。

メインメニュー数 (MaxLayM)
メインメニューの項目数。「3」とすれば3個のメニューを作れます。 この数分だけ、MaxLayS[x]Top[x]の指定を行う必要があります。 また、BODY要素にも相当数のDIV要素とそれに対応したid属性を指定する必要があります。 下記の例は、メインメニュー1個目で「id="iL10"」となっています。2個目だと「id="iL20"」です。 この時、「onmouseover="Mover(1,0)"」「name="jL10"」は 「onmouseover="Mover(2,0)"」「name="jL20"」として下さい。
<div class="Style1" id="iL10">
<a href="javascript:void(0);" onmouseover="Mover(1,0)" onmouseout="Mout()">
<img name="jL10" src="image/plus.gif" border=0> List1
</a>
</div>
この他、スクリプト部分の配列宣言を必要に応じて増やす必要があります。例を参考にして下さい。 例では、メインメニュー3個の場合で、4個目は「X[4] = new Array();」を増やします。またサブメニュー分の 「X[4][0] = new Array();」は必須で、サブメニュー分だけ「X[4][1] = new Array();」を増やします。
	X[1] = new Array();
		//MaxLayS[1]分用意
		X[1][0] = new Array();
		X[1][1] = new Array();
		X[1][2] = new Array();
		X[1][3] = new Array();
	X[2] = new Array();
		//MaxLayS[2]分用意
		X[2][0] = new Array();
		X[2][1] = new Array();
		X[2][2] = new Array();
	X[3] = new Array();
		//MaxLayS[3]分用意
		X[3][0] = new Array();
		X[3][1] = new Array();
メインメニュー内容
上記例の「List1」の部分は好きに変更しても構いません。また、「Style1」でもスタイルの変更は可能です。 当然ながら、クラス属性を変更することも可能です。ただし、id属性名の変更は不可です。
サブメニュー数 (MaxLayS[x])
サブメニューの項目数。「x」の部分は何番目のメインメニューに対応しているかを示します。 例えば「3」であれば3番目のメインメニューに対するものです。 この数字を「1」とすれば1個のサブメニューを作れます。 また、BODY要素にも相当数のDIV要素とそれに対応したid属性を指定する必要があります。 下記の例は、メインメニュー3個目のサブメニュー1個目に対するものです。 「id="iL31"」となっています。2個目だと「id="iL32"」です。 この時、「onmouseover="Mover(3,1)"」「name="jL31"」は 「onmouseover="Mover(3,2)"」「name="jL32"」として下さい。
<div class="Style1" id="iL31">
<a href="javascript:void(0);" onmouseover="Mover(3,1)" onmouseout="Mout()">
<img name="jL31" src="image/plus.gif" border=0> List3-1
</a>
</div>
この他、スクリプト部分の配列宣言を必要に応じて増やす必要があります。例を参考にして下さい。 例では、メインメニュー3のサブメニューを1個の場合で、2個目は「X[3][2] = new Array();」を増やします。
	X[1] = new Array();
		//MaxLayS[1]分用意
		X[1][0] = new Array();
		X[1][1] = new Array();
		X[1][2] = new Array();
		X[1][3] = new Array();
	X[2] = new Array();
		//MaxLayS[2]分用意
		X[2][0] = new Array();
		X[2][1] = new Array();
		X[2][2] = new Array();
	X[3] = new Array();
		//MaxLayS[3]分用意
		X[3][0] = new Array();
		X[3][1] = new Array();
サブメニュー内容
上記例の「List3-1」の部分は好きに変更しても構いません。また、「Style1」でもスタイルの変更は可能です。 当然ながら、クラス属性を変更することも可能です。ただし、id属性名の変更は不可です。
表示位置
CSSリファレンスに従って、変更可。
Top[x]
メインメニューのY座標をピクセルで指定。Top[1]のみ有効。2項目以降は自動で決まります。
mLeft
メインメニューのX座標をピクセルで指定。
sLeft
サブメニューのX座標をピクセルで指定。
csLeft
コンテンツのX座標をピクセルで指定。
Wid
メイン、サブメニューの幅をピクセルで指定。
Hei
メイン、サブメニューの高さをピクセルで指定。
cWid
コンテンツの幅をピクセルで指定。
cHei
コンテンツの高さをピクセルで指定。
Space
メニュー間隔をピクセルで指定。
画像
プラス、マイナスの画像ファイルを指定します。 HTMLファイルに対する相対パス、または絶対パスで指定します。 プラスマークは非展開時、マイナスマークは展開時で、それぞれ以下のように設定しています。
プラス
plus.src = "image/plus.gif";
マイナス
minus.src = "image/minus.gif";

対応ブラウザ

IE4,IE5,NN4,N6

サンプル

サンプルを見る] [ダウンロード

[Go To Top]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>エクスプローラ風2段ツリー</title>

<style type="text/css">
<!--
.Style1{		/*for Main,SubMenu*/
	position:			absolute;
	font-weight:		bold;
	visibility:			hidden;
}
.Style2{		/*for Contents*/
	position:			absolute;
	font-size:			12pt;
	font-weight:		bold;
	color:				#c00;
	background-color:	#fcc;
	margin:				0px;
	padding:			1px;
	border:				1px solid #f33;
	visibility:			hidden;
}
.title{
	font-size:			16pt;
	font-weight:		bold;
	color:				#00c;
	background-color:	#ccf;
	margin:				0px;
	padding:			5px;
	border:				2px solid #33f;
}
/*Style of Anchor*/
A{
	text-decoration:	none;
}
A:Link{
	color:				#0000ff;
}
A:Visited{
	color:				#6666ff;
}
A:Active{
	color:				#0000ff;
}
A:Hover{
	color:				#ff0000;
	text-decoration:	underline;
	background-color:	#fdd;
}
-->
</style>


<script language="JavaScript1.2">
<!--
//--------------ここから設定
var MaxLayM = 3;					//MainMenuの最大数
var MaxLayS = new Array();
    MaxLayS[1] = 3;				//SubMenu(Main1)の最大数
    MaxLayS[2] = 2;				//SubMenu(Main2)の最大数
    MaxLayS[3] = 1;				//SubMenu(Main3)の最大数
var Top = new Array();
	Top[1] = 80;					//MainMenu - 1 のY座標(top)
	Top[2] = 100;					//MainMenu - 2 のY座標(top)
	Top[3] = 120;					//MainMenu - 3 のY座標(top)
var mLeft = 20;						//MainMenu のX座標(left)
var sLeft = 40;						//SubMenu のX座標(left)
var csLeft = 60;					//Contents のX座標(left)
var Wid = 200;						//Main,SubMenu - width
var Hei = 20;						//Main,SubMenu - height
var cWid = 200;						//Contents - width
var cHei = 25;						//Contents - height
var Space = 7;						//リスト同士の隙間(pixel)

var plus = new Image(0,0);
	plus.src = "image/plus.gif";	//+の画像
var minus = new Image(0,0);
	minus.src = "image/minus.gif";	//-の画像
//--------------ここまで設定

var X = new Array();
	X[1] = new Array();
		//MaxLayS[1]分用意
		X[1][0] = new Array();
		X[1][1] = new Array();
		X[1][2] = new Array();
		X[1][3] = new Array();
	X[2] = new Array();
		//MaxLayS[2]分用意
		X[2][0] = new Array();
		X[2][1] = new Array();
		X[2][2] = new Array();
	X[3] = new Array();
		//MaxLayS[3]分用意
		X[3][0] = new Array();
		X[3][1] = new Array();
var Xc = new Array();
	Xc[1] = new Array();
		//MaxLayS[1]分用意
		Xc[1][0] = new Array();
		Xc[1][1] = new Array();
		Xc[1][2] = new Array();
		Xc[1][3] = new Array();
	Xc[2] = new Array();
		//MaxLayS[2]分用意
		Xc[2][0] = new Array();
		Xc[2][1] = new Array();
		Xc[2][2] = new Array();
	Xc[3] = new Array();
		//MaxLayS[3]分用意
		Xc[3][0] = new Array();
		Xc[3][1] = new Array();

var T = 0;
var L = 1;
var H = 2;
var W = 3;
var V = 4;
var IMG = 5;

var Lflag1 = false;
var Lflag2 = false;
var LK1,LK2;

if(document.getElementById){
	document.onmousedown = Mclick;
}else if(document.all){
	document.onmousedown = Mclick;
}else if(document.layers){
	window.captureEvents(Event.MOUSEDOWN);
	window.onmousedown = Mclick;
}

function Mover(m,n){
	if(Lflag1){
		LK1 = m;

		LK2 = n;
		Lflag2 = true;
	}
}
function Mout(){
	if(Lflag1){
		Lflag2 = false;
	}
}
function Mclick(){
	if(Lflag2){
		Correct(LK1,LK2);
	}
}

function Init(){
	SetCord();
	LayerSet();
	Lflag1 = true;
}
//Visibility処理
function Correct(k1,k2){
	var f_L,Z;
	f_L = false;
	if(k2 == 0){	//MainMenu
		for(j = 1;j <= MaxLayS[k1];j++){
			if(X[k1][j][V] || Xc[k1][j][V]){
				f_L = true;
			}
		}
		if(f_L){
			for(j = 1;j <= MaxLayS[k1];j++){
				X[k1][j][V] = 0;
				Xc[k1][j][V] = 0;
				X[k1][j][IMG] = 0;
			}
			X[k1][k2][IMG] = 0;
		}else{
			for(j = 1;j <= MaxLayS[k1];j++){
				X[k1][j][V] = 1;
			}
			X[k1][k2][IMG] = 1;
		}
	}else{
		if(Xc[k1][k2][V]){
			f_L = true;
		}
		if(f_L){
			Xc[k1][k2][V] = 0;
			X[k1][k2][IMG] = 0;
		}else{
			Xc[k1][k2][V] = 1;
			X[k1][k2][IMG] = 1;
		}
	}
	LayerSet();
}

//初期座標のセット
function SetCord(){
	for(i = 1;i <= MaxLayM;i++){
		X[i][0][T] = Top[i];
		X[i][0][L] = mLeft;
		X[i][0][H] = Hei;
		X[i][0][W] = Wid;
		X[i][0][V] = 1;
		X[i][0][IMG] = 0;
		for(j = 1;j <= MaxLayS[i];j++){
			X[i][j][T] = Top[i];
			X[i][j][L] = sLeft;
			X[i][j][H] = Hei;
			X[i][j][W] = Wid;
			X[i][j][V] = 0;
			X[i][j][IMG] = 0;
			Xc[i][j][T] = Top[i];
			Xc[i][j][L] = csLeft;
			Xc[i][j][H] = cHei;
			Xc[i][j][W] = cWid;
			Xc[i][j][V] = 0;
		}
	}
}

//レイヤーの座標セット
function LayerSet(){
	SetLayerCord();
    if(document.getElementById){
		for(i = 1;i <= MaxLayM;i++){
			document.getElementById("iL"+i+"0").style.top = X[i][0][T];
			document.getElementById("iL"+i+"0").style.left = X[i][0][L];
			document.getElementById("iL"+i+"0").style.height = X[i][0][H];
			document.getElementById("iL"+i+"0").style.width = X[i][0][W];
			if(X[i][0][V]){
				document.getElementById("iL"+i+"0").style.visibility = "visible";
			}else{
				document.getElementById("iL"+i+"0").style.visibility = "hidden";
			}
			if(X[i][0][IMG]){
				document.images["jL"+i+"0"].src = minus.src;
			}else{
				document.images["jL"+i+"0"].src = plus.src;
			}
			for(j = 1;j <= MaxLayS[i];j++){
				document.getElementById("iL"+i+j).style.top = X[i][j][T];
				document.getElementById("iL"+i+j).style.left = X[i][j][L];
				document.getElementById("iL"+i+j).style.height = X[i][j][H];
				document.getElementById("iL"+i+j).style.width = X[i][j][W];
				if(X[i][j][V]){
					document.getElementById("iL"+i+j).style.visibility = "visible";
				}else{
					document.getElementById("iL"+i+j).style.visibility = "hidden";
				}
				if(X[i][j][IMG]){
					document.images["jL"+i+j].src = minus.src;
				}else{
					document.images["jL"+i+j].src = plus.src;
				}
				document.getElementById("iLc"+i+j).style.top = Xc[i][j][T];
				document.getElementById("iLc"+i+j).style.left = Xc[i][j][L];
				document.getElementById("iLc"+i+j).style.height = Xc[i][j][H];
				document.getElementById("iLc"+i+j).style.width = Xc[i][j][W];
				if(Xc[i][j][V]){
					document.getElementById("iLc"+i+j).style.visibility = "visible";
				}else{
					document.getElementById("iLc"+i+j).style.visibility = "hidden";
				}
			}
		}
    }else if(document.all){
		for(i = 1;i <= MaxLayM;i++){
			document.all("iL"+i+"0").style.pixelTop = X[i][0][T];
			document.all("iL"+i+"0").style.pixelLeft = X[i][0][L];
			document.all("iL"+i+"0").style.height = X[i][0][H];
			document.all("iL"+i+"0").style.width = X[i][0][W];
			if(X[i][0][V]){
				document.all("iL"+i+"0").style.visibility = "visible";
			}else{
				document.all("iL"+i+"0").style.visibility = "hidden";
			}
			if(X[i][0][IMG]){
				document.images["jL"+i+"0"].src = minus.src;
			}else{
				document.images["jL"+i+"0"].src = plus.src;
			}
			for(j = 1;j <= MaxLayS[i];j++){
				document.all("iL"+i+j).style.pixelTop = X[i][j][T];
				document.all("iL"+i+j).style.pixelLeft = X[i][j][L];
				document.all("iL"+i+j).style.height = X[i][j][H];
				document.all("iL"+i+j).style.width = X[i][j][W];
				if(X[i][j][V]){
					document.all("iL"+i+j).style.visibility = "visible";
				}else{
					document.all("iL"+i+j).style.visibility = "hidden";
				}
				if(X[i][j][IMG]){
					document.images["jL"+i+j].src = minus.src;
				}else{
					document.images["jL"+i+j].src = plus.src;
				}
				document.all("iLc"+i+j).style.pixelTop = Xc[i][j][T];
				document.all("iLc"+i+j).style.pixelLeft = Xc[i][j][L];
				document.all("iLc"+i+j).style.height = Xc[i][j][H];
				document.all("iLc"+i+j).style.width = Xc[i][j][W];
				if(Xc[i][j][V]){
					document.all("iLc"+i+j).style.visibility = "visible";
				}else{
					document.all("iLc"+i+j).style.visibility = "hidden";
				}
			}
		}
	}else if(document.layers){
		for(i = 1;i <= MaxLayM;i++){
			document.layers["iL"+i+"0"].top = X[i][0][T];
			document.layers["iL"+i+"0"].left = X[i][0][L];
			document.layers["iL"+i+"0"].height = X[i][0][H];
			document.layers["iL"+i+"0"].width = X[i][0][W];
			if(X[i][0][V]){
				document.layers["iL"+i+"0"].visibility = "show";
			}else{
				document.layers["iL"+i+"0"].visibility = "hide";
			}
			if(X[i][0][IMG]){
				document.layers["iL"+i+"0"].document.images["jL"+i+"0"].src = minus.src;
			}else{
				document.layers["iL"+i+"0"].document.images["jL"+i+"0"].src = plus.src;
			}
			for(j = 1;j <= MaxLayS[i];j++){
				document.layers["iL"+i+j].top = X[i][j][T];
				document.layers["iL"+i+j].left = X[i][j][L];
				document.layers["iL"+i+j].height = X[i][j][H];
				document.layers["iL"+i+j].width = X[i][j][W];
				if(X[i][j][V]){
					document.layers["iL"+i+j].visibility = "show";
				}else{
					document.layers["iL"+i+j].visibility = "hide";
				}
				if(X[i][j][IMG]){
					document.layers["iL"+i+j].document.images["jL"+i+j].src = minus.src;
				}else{
					document.layers["iL"+i+j].document.images["jL"+i+j].src = plus.src;
				}
				document.layers["iLc"+i+j].top = Xc[i][j][T];
				document.layers["iLc"+i+j].left = Xc[i][j][L];
				document.layers["iLc"+i+j].height = Xc[i][j][H];
				document.layers["iLc"+i+j].width = Xc[i][j][W];
				if(Xc[i][j][V]){
					document.layers["iLc"+i+j].visibility = "show";
				}else{
					document.layers["iLc"+i+j].visibility = "hide";
				}
			}
		}
	}
}

//レイヤー位置の再演算
function SetLayerCord(){
	H0 = X[1][0][H];
	Y0 = X[1][0][T] - H0 - Space;
	for(i = 1;i <= MaxLayM;i++){
		if(X[i][0][V]){
			Y1 = Y0 + H0 + Space;
			X[i][0][T] = Y1;
			Y0 = Y1;
			H0 = X[i][0][H];
		}
		for(j = 1;j <= MaxLayS[i];j++){
			if(X[i][j][V]){
				Y1 = Y0 + H0 + Space;
				X[i][j][T] = Y1;
				Y0 = Y1;
				H0 = X[i][j][H];
			}
			if(Xc[i][j][V]){
				Y1 = Y0 + H0 + Space;
				Xc[i][j][T] = Y1;
				Y0 = Y1;
				H0 = Xc[i][j][H];
			}
		}
	}
}

// -->
</script>

</head>

<body onload="Init()">

<div class="title">エクスプローラ風2段ツリー</div>

<!-- 1 -->
<div class="Style1" id="iL10">
<a href="javascript:void(0);" onmouseover="Mover(1,0)" onmouseout="Mout()"><img name="jL10" src="image/plus.gif" border=0> List1</a>
</div>

<div class="Style1" id="iL11">
<a href="JavaScript:void(0);" onmouseover="Mover(1,1)" onmouseout="Mout()"><img name="jL11" src="image/plus.gif" border=0> List1-1</a>
</div>
<div class="Style2" id="iLc11">
CONTENTS11
</div>

<div class="Style1" id="iL12">
<a href="JavaScript:void(0);" onmouseover="Mover(1,2)" onmouseout="Mout()"><img name="jL12" src="image/plus.gif" border=0> List1-2</a>
</div>
<div class="Style2" id="iLc12">
CONTENTS12
</div>

<div class="Style1" id="iL13">
<a href="JavaScript:void(0);" onmouseover="Mover(1,3)" onmouseout="Mout()"><img name="jL13" src="image/plus.gif" border=0> List1-3</a>
</div>
<div class="Style2" id="iLc13">
CONTENTS13
</div>


<!-- 2 -->
<div class="Style1" id="iL20">
<a href="JavaScript:void(0);" onmouseover="Mover(2,0)" onmouseout="Mout()"><img name="jL20" src="image/plus.gif" border=0> List2</a>
</div>

<div class="Style1" id="iL21">
<a href="JavaScript:void(0);" onmouseover="Mover(2,1)" onmouseout="Mout()"><img name="jL21" src="image/plus.gif" border=0> List2-1</a>
</div>
<div class="Style2" id="iLc21">
CONTENTS21
</div>

<div class="Style1" id="iL22">
<a href="JavaScript:void(0);" onmouseover="Mover(2,2)" onmouseout="Mout()"><img name="jL22" src="image/plus.gif" border=0> List2-2</a>
</div>
<div class="Style2" id="iLc22">
CONTENTS22
</div>


<!-- 3 -->
<div class="Style1" id="iL30">
<a href="JavaScript:void(0);" onmouseover="Mover(3,0)" onmouseout="Mout()"><img name="jL30" src="image/plus.gif" border=0> List3</a>
</div>

<div class="Style1" id="iL31">
<a href="JavaScript:void(0);" onmouseover="Mover(3,1)" onmouseout="Mout()"><img name="jL31" src="image/plus.gif" border=0> List3-1</a>
</div>
<div class="Style2" id="iLc31">
CONTENTS31
</div>


</body>
</html>

修正履歴

2000.10.04
ページ読込時のゴミ表示対応のため、visibility:hiddenを追加
2001.9.02
N6対応。
[Go To Top]

Last modified Sep,2001
Copyright(C)2000 T.Miyazaki , All Rights Reserved.