在網(wǎng)上發(fā)現(xiàn)了一個(gè)很不錯(cuò)的樹的例子。是外國(guó)人寫的,可以免費(fèi)使用和修改(商用或個(gè)人使用都成)。
上星期正好沒什么事情,本著拿來(lái)主義的精神,就研究了一下,寫了一個(gè)使用說(shuō)明也給原代碼加了點(diǎn)注釋。
Tigra Tree Menu scipt包含三個(gè)文件:
tree.js?????????? 構(gòu)造樹的js代碼
tree_items.js???? 樹結(jié)構(gòu)文件.構(gòu)造樹的數(shù)組及一些配置被定義在此
tree_tpl.js?????? 默認(rèn)的圖標(biāo)配置文件-可以被替換為用戶自定義圖標(biāo)
tree_items.js中的數(shù)組是類似:
var TREE_ITEMS = [
? ["A0",null,
??? ["A00",null,
????? ["A000"]
??? ],
??? ["A01",null,
????? ["A010","javascript:alert("A010")"]
??? ],
??? ["A02"]
? ],
? ["A1",null,
??? ["A10"],
??? ["A11",null,
????? ["A110"]
??? ]
? ]
];
一、每個(gè)樹節(jié)點(diǎn)都是包含一個(gè)或多個(gè)元素的數(shù)組.
1、如果節(jié)點(diǎn)是葉子節(jié)點(diǎn),它對(duì)應(yīng)的數(shù)組類似:
["A010","javascript:alert("A010")"]
其中第一個(gè)元素是節(jié)點(diǎn)顯示的text,第二個(gè)元素是點(diǎn)擊節(jié)點(diǎn)時(shí)執(zhí)行的js代碼,也可以是一個(gè)鏈接地址,如果在tree_tpl.js里面有配target的話,點(diǎn)擊節(jié)點(diǎn)將會(huì)在target所指位置打開這個(gè)鏈接地址,
如果不需要點(diǎn)擊時(shí)有執(zhí)行js代碼或有鏈接,第二個(gè)元素可以不寫.
2、如果節(jié)點(diǎn)是個(gè)樹節(jié)點(diǎn),它對(duì)應(yīng)的數(shù)組類似:
["A1",null,
? ["A10"],??????????????????????????? <----A1的下級(jí)結(jié)點(diǎn),葉子結(jié)點(diǎn)
? ["A11",null,??????????????????????? <----A1的下級(jí)結(jié)點(diǎn),樹結(jié)點(diǎn)
??? ["A110"]
? ]
]
其中第一個(gè)元素是節(jié)點(diǎn)顯示的text,第二個(gè)元素顯示的是點(diǎn)擊節(jié)點(diǎn)時(shí)執(zhí)行的js代碼,也可以是一個(gè)鏈接地址,如果在tree_tpl.js里面有配target的話,點(diǎn)擊節(jié)點(diǎn)將會(huì)在target所指位置打開這個(gè)鏈接地址,
如果不需要點(diǎn)擊時(shí)有執(zhí)行js代碼或有鏈接,第二個(gè)元素必須寫成null(不能不寫),之后的元素是數(shù)組,存放這個(gè)元素的下級(jí)節(jié)點(diǎn)信息.
二、trees數(shù)組存放每一棵樹的信息.
例,如果頁(yè)面上有兩棵樹,則第一棵樹的信息存放在trees[0]中,第二棵樹的信息存放在trees[1]中.
三、每個(gè)節(jié)點(diǎn)的信息即存放在其上級(jí)的a_children數(shù)組中,同時(shí)也存放在整棵樹a_index數(shù)組中.
例如,結(jié)點(diǎn)A000,其信息對(duì)象即存放在其上級(jí)的a_children數(shù)組的第0位,也存放在整棵樹的a_index數(shù)組的第2位
?
tree.js的代碼:
?
//?Title:?Tigra?Tree
//?Description:?See?the?demo?at?url
//?URL:?http://www.softcomplex.com/products/tigra_menu_tree/
//?Version:?1.1
//?Date:?11-12-2002?(mm-dd-yyyy)
//?Notes:?This?script?is?free.?Visit?official?site?for?further?details.

function?tree?(a_items,?a_template)?{
????this.a_tpl??????=?a_template;
????this.a_config???=?a_items;
????this.o_root?????=?this;
????this.a_index????=?[];
????this.o_selected?=?null;
????this.n_depth????=?-1;
????this.n_id?=?trees.length;
????trees[this.n_id]?=?this;

??//圖像預(yù)裝載
????var?o_icone?=?new?Image(),
??o_iconl?=?new?Image();
??//icon_e,和icon_l是一定有配的
????o_icone.src?=?a_template['icon_e'];
????o_iconl.src?=?a_template['icon_l'];
????a_template['im_e']?=?o_icone;
????a_template['im_l']?=?o_iconl;

????for?(var?i?=?0;?i?<?64;?i++)
????????if?(a_template['icon_'?+?i])?{//如果配置文件里面有配圖像地址,則需預(yù)裝載
????????????var?o_icon?=?new?Image();
????????????a_template['im_'?+?i]?=?o_icon;
????????????o_icon.src?=?a_template['icon_'?+?i];
????????}
????
??//折疊/展開節(jié)點(diǎn)
????this.toggle?=?function?(n_id)?{????var?o_item?=?this.a_index[n_id];?o_item.open(o_item.b_opened)?};

??//選中節(jié)點(diǎn)
????this.select?=?function?(n_id)?{?return?this.a_index[n_id].select();?};

??//從節(jié)點(diǎn)上移開
????this.mout???=?function?(n_id)?{?this.a_index[n_id].upstatus(true)?};

??//移到節(jié)點(diǎn)上
????this.mover??=?function?(n_id)?{?this.a_index[n_id].upstatus()?};

????this.a_children?=?[];

????for?(var?i?=?0;?i?<?a_items.length;?i++)
????????new?tree_item(this,?i);


??//開始生成結(jié)點(diǎn)
????for?(var?i?=?0;?i?<?this.a_children.length;?i++)?{
????????document.write(this.a_children[i].init());?//根結(jié)點(diǎn)
????????this.a_children[i].open();//展開,如果希望折疊到根結(jié)點(diǎn)調(diào)用this.a_children[i].open(true);

????//需要全部展開節(jié)點(diǎn)時(shí),調(diào)用以下這一段代碼,add?by?linxf
????if(this.a_children[i].a_children.length?>?0){
??????openChildNode(this.a_children[i]);
????}
????}
}

/*
?*?生成并打開o_parent的所有子節(jié)點(diǎn)
?*?add?by?linxf
?*/
function?openChildNode(o_parent){
??for?(var?i?=?0;?i?<?o_parent.a_children.length;?i++)?{
????o_parent.a_children[i].open();
????if(o_parent.a_children[i].a_children.length?>?0){
??????openChildNode(o_parent.a_children[i]);
????}
??}
}

function?tree_item?(o_parent,?n_order)?{
????this.n_depth??=?o_parent.n_depth?+?1;//節(jié)點(diǎn)的深度
????this.a_config?=?o_parent.a_config[n_order?+?(this.n_depth???2?:?0)];//每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的數(shù)組
????if?(!this.a_config)?return;

????this.o_root????=?o_parent.o_root;?//trees數(shù)組中放置這棵樹信息的對(duì)應(yīng)元素,trees[x]
????this.o_parent??=?o_parent;
????this.n_order???=?n_order;
????this.b_opened??=?!this.n_depth;

??//在整棵樹的a_index數(shù)組的最末位放置自身
????this.n_id?=?this.o_root.a_index.length;
????this.o_root.a_index[this.n_id]?=?this;

??//在上級(jí)的a_children數(shù)組的相應(yīng)位置(n_order)放置自身
????o_parent.a_children[n_order]?=?this;

????this.a_children?=?[];
??//遞歸構(gòu)造
????for?(var?i?=?0;?i?<?this.a_config.length?-?2;?i++)
????????new?tree_item(this,?i);

????this.get_icon?=?item_get_icon;
????this.open?????=?item_open;
????this.select???=?item_select;
????this.init?????=?item_init;
????this.upstatus?=?item_upstatus;
????this.is_last??=?function?()?{//是否是(父結(jié)點(diǎn)的所有子結(jié)點(diǎn)中的)最后一個(gè)結(jié)點(diǎn)
????return?this.n_order?==?this.o_parent.a_children.length?-?1?
??};
}

/*
?*?展開/折壘節(jié)點(diǎn)
?*/
function?item_open?(b_close)?{
????var?o_idiv?=?get_element('i_div'?+?this.o_root.n_id?+?'_'?+?this.n_id);
????if?(!o_idiv)?return;
????
????if?(!o_idiv.innerHTML)?{//下級(jí)結(jié)點(diǎn)(用div圈起來(lái)的),如果里面沒有內(nèi)容,生成內(nèi)容,如果有內(nèi)容,則展開(折疊)div
????????var?a_children?=?[];
????????for?(var?i?=?0;?i?<?this.a_children.length;?i++)
????????????a_children[i]=?this.a_children[i].init();
????????o_idiv.innerHTML?=?a_children.join('');
????}

????o_idiv.style.display?=?(b_close???'none'?:?'block');
????
????this.b_opened?=?!b_close;
????var?o_jicon?=?document.images['j_img'?+?this.o_root.n_id?+?'_'?+?this.n_id],
????????o_iicon?=?document.images['i_img'?+?this.o_root.n_id?+?'_'?+?this.n_id];
????if?(o_jicon)?o_jicon.src?=?this.get_icon(true);
????if?(o_iicon)?o_iicon.src?=?this.get_icon();
????this.upstatus();
}

/*
?*?選擇結(jié)點(diǎn)
?*/
function?item_select?(b_deselect)?{
????if?(!b_deselect)?{
????????var?o_olditem?=?this.o_root.o_selected;//取上一次被選中的節(jié)點(diǎn)
????????this.o_root.o_selected?=?this;//把當(dāng)前被選中的節(jié)點(diǎn)存入this.o_root.o_selected
????????if?(o_olditem)?o_olditem.select(true);//將上次選中的節(jié)點(diǎn)字體變?yōu)閚ormal
????}

????var?o_iicon?=?document.images['i_img'?+?this.o_root.n_id?+?'_'?+?this.n_id];
????if?(o_iicon)?o_iicon.src?=?this.get_icon();
????get_element('i_txt'?+?this.o_root.n_id?+?'_'?+?this.n_id).style.fontWeight?=?b_deselect???'normal'?:?'bold';
????
????this.upstatus();
????return?Boolean(this.a_config[1]);
}

function?item_upstatus?(b_clear)?{
????window.setTimeout('window.status="'?+?(b_clear???''?:?this.a_config[0]?+?(this.a_config[1]???'?('+?this.a_config[1]?+?')'?:?''))?+?'"',?10);
}

/*
?*?結(jié)點(diǎn)初始化
?*/
function?item_init?()?{
????var?a_offset?=?[],
????????o_current_item?=?this.o_parent;
????for?(var?i?=?this.n_depth;?i?>?1;?i--)?{
????????a_offset[i]?=?'<img?src="'?+?this.o_root.a_tpl[o_current_item.is_last()???'icon_e'?:?'icon_l']?+?'"?border="0"?align="absbottom">';
????????o_current_item?=?o_current_item.o_parent;
????}

??//返回構(gòu)造的html語(yǔ)句,this.a_config[1]為href的值,this.a_config[0]為節(jié)點(diǎn)的內(nèi)容
????return?'<table?cellpadding="0"?cellspacing="0"?border="0"><tr><td?nowrap>'?+?(this.n_depth???a_offset.join('')?+?(this.a_children.length
??????????'<a?href="javascript:?trees['?+?this.o_root.n_id?+?'].toggle('?+?this.n_id?+?')"?onmouseover="trees['?+?this.o_root.n_id?+?'].mover('?+?this.n_id?+?')"?onmouseout="trees['?+?this.o_root.n_id?+?'].mout('?+?this.n_id?+?')"><img?src="'?+?this.get_icon(true)?+?'"?border="0"?align="absbottom"?name="j_img'?+?this.o_root.n_id?+?'_'?+?this.n_id?+?'">a>'
????????:?'<img?src="'?+?this.get_icon(true)?+?'"?border="0"?align="absbottom">')?:?'')?
????????+?'<a?href="'?+?this.a_config[1]?+?'"?target="'?+?this.o_root.a_tpl['target']?+?'"?onclick="return?trees['?+?this.o_root.n_id?+?'].select('?+?this.n_id?+?')"?ondblclick="trees['?+?this.o_root.n_id?+?'].toggle('?+?this.n_id?+?')"?onmouseover="trees['?+?this.o_root.n_id?+?'].mover('?+?this.n_id?+?')"?onmouseout="trees['?+?this.o_root.n_id?+?'].mout('?+?this.n_id?+?')"?class="t'?+?this.o_root.n_id?+?'i"?id="i_txt'?+?this.o_root.n_id?+?'_'?+?this.n_id?+?'"><img?src="'?+?this.get_icon()?+?'"?border="0"?align="absbottom"?name="i_img'?+?this.o_root.n_id?+?'_'?+?this.n_id?+?'"?class="t'?+?this.o_root.n_id?+?'im">'?+?this.a_config[0]?+?'a>td>tr>table>'?
????+?(this.a_children.length???'<div?id="i_div'?+?this.o_root.n_id?+?'_'?+?this.n_id?+?'"?style="display:none">div>'?:?'');
??//節(jié)點(diǎn)this.a_config[0]所有的下級(jí)都被此層包圍起來(lái)
}

function?item_get_icon?(b_junction)?{
????return?this.o_root.a_tpl['icon_'?+?((this.n_depth???0?:?32)?+?(this.a_children.length???16?:?0)?+?(this.a_children.length?&&?this.b_opened???8?:?0)?+?(!b_junction?&&?this.o_root.o_selected?==?this???4?:?0)?+?(b_junction???2?:?0)?+?(b_junction?&&?this.is_last()???1?:?0))];
}

var?trees?=?[];
get_element?=?document.all??
????function?(s_id)?{?return?document.all[s_id]?}?:
????function?(s_id)?{?return?document.getElementById(s_id)?};


function?expand_or_collapse_all?(o_tree,?b_collapse)?{
??for?(var?i?=?0;?i?<?o_tree.a_index.length;?i++)?{
????var?o_item?=?o_tree.a_index[i];
????o_item.open(b_collapse);
??}
}
?
?
tree_tpl.js的代碼:
var?TREE_TPL?=?{
??//超鏈接的target,可能的值有:_blank,?_parent,?_search,?_self?and?_top
????'target'??:?'frameset',????

??//空的圖標(biāo)和豎線圖標(biāo)
????'icon_e'??:?'icons/empty.gif',?//?empty?image
????'icon_l'??:?'icons/line.gif',??//?vertical?line

???//以4疊加
??'icon_32'?:?'icons/base.gif',???//?root?leaf?icon?normal
??'icon_36'?:?'icons/base.gif',???//?root?leaf?icon?selected
????
????'icon_48'?:?'icons/base.gif',???//?root?icon?normal
????'icon_52'?:?'icons/base.gif',???//?root?icon?selected
????'icon_56'?:?'icons/base.gif',???//?root?icon?opened
????'icon_60'?:?'icons/base.gif',???//?root?icon?selected
????
????'icon_16'?:?'icons/folder.gif',?//?node?icon?normal
????'icon_20'?:?'icons/folderopen.gif',?//?node?icon?selected
????'icon_24'?:?'icons/folderopen.gif',?//?node?icon?opened
????'icon_28'?:?'icons/folderopen.gif',?//?node?icon?selected?opened

????'icon_0'??:?'icons/page.gif',?//?leaf?icon?normal
????'icon_4'??:?'icons/page.gif',?//?leaf?icon?selected
????
??//以bottom結(jié)尾的圖標(biāo)都有一個(gè)向下的豎線尾巴
????'icon_2'??:?'icons/joinbottom.gif',?//?junction?for?leaf
????'icon_3'??:?'icons/join.gif',???????//?junction?for?last?leaf
????'icon_18'?:?'icons/plusbottom.gif',?//?junction?for?closed?node
????'icon_19'?:?'icons/plus.gif',???????//?junctioin?for?last?closed?node
????'icon_26'?:?'icons/minusbottom.gif',//?junction?for?opened?node
????'icon_27'?:?'icons/minus.gif'???????//?junctioin?for?last?opended?node tree.html的代碼:
<html>
<head>

??<style>
????a,?A:link,?a:visited,?a:active,?A:hover

??????{
}{color:?#000000;?text-decoration:?none;?font-family:?Tahoma,?Verdana;?font-size:?12px}
??style>
??<script?language="JavaScript"?src="tree.js">script>
??<script?language="JavaScript"?src="tree_items.js">script>
??<script?language="JavaScript"?src="tree_tpl.js">script>
??<script?language="JavaScript"?src="strUtil.js">script>
head>

<body>??

??<SCRIPT?LANGUAGE="JavaScript">
????new?tree?(TREE_ITEMS,?TREE_TPL);
??SCRIPT>
??<button?onClick="expand_or_collapse_all(trees[0],true)">Collapse?Tree1button>
??<button?onClick="expand_or_collapse_all(trees[0],false)">Expand?Tree1button><br>


??<SCRIPT?LANGUAGE="JavaScript">
????new?tree?(TREE_ITEMS,?TREE_TPL);
??SCRIPT>
??<button?onClick="expand_or_collapse_all(trees[1],true)">Collapse?Tree2button>
??<button?onClick="expand_or_collapse_all(trees[1],false)">Expand?Tree2button>

body>
html>