III. 添加節(jié)點(diǎn)的方法:
在上面的示例中我們總共接觸到了五種添加目錄樹節(jié)點(diǎn)的方法,先看它們的語法原型:
1.tree.add(toNode,relation,text,key,ico,exeCategory,exeArg)
2.root.add(text,ico,exeCategory,exeArg)
3.root.addLink(url,text,target,ico)
4.node.add(text,ico,exeCategory,exeArg)
5.node.addLink(url,text,target,ico)
6.tree.pathParse(path,pathSeparator,listSeparator)
方法1的功能最全面,涵蓋了方法2-5,但部分參數(shù)我們很少用到,所以用的較多的還是方法2-5。root對象的add方法總是添加第一級的節(jié)點(diǎn),節(jié)點(diǎn)node對象的add方法用于添加節(jié)點(diǎn)的子節(jié)點(diǎn)。addLink方法方便我們添加有網(wǎng)址鏈接的節(jié)點(diǎn)。pathParse方法可解釋一個(gè)路徑列表生成對應(yīng)的樹結(jié)構(gòu)。
IV. 節(jié)點(diǎn)關(guān)系:
目錄樹控件程序?qū)τ跇浣Y(jié)構(gòu)有一個(gè)明晰的邏輯表述,這一點(diǎn)表現(xiàn)在樹節(jié)點(diǎn)對象的下面幾種關(guān)系上:
node.first -- 節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn),若無子節(jié)點(diǎn)則為null
node.last -- 節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn),若無子節(jié)點(diǎn)則為null
node.next -- 節(jié)點(diǎn)下一個(gè)相鄰的子節(jié)點(diǎn),若node是該層上最后一個(gè)結(jié)點(diǎn)則為null
node.prev -- 節(jié)點(diǎn)上一個(gè)相鄰的子節(jié)點(diǎn),若node是該層上第一個(gè)結(jié)點(diǎn)則為null
node.parent -- 節(jié)點(diǎn)的父節(jié)點(diǎn)
node.chidren -- 節(jié)點(diǎn)的子節(jié)點(diǎn)(它是一個(gè)的集合數(shù)組,第個(gè)元素是一個(gè)節(jié)點(diǎn)對象)
對于根對象root:
root.first是第一級節(jié)點(diǎn)的第一個(gè)節(jié)點(diǎn),root.last是第一級節(jié)點(diǎn)的最后一個(gè)節(jié)點(diǎn),root.chidren是第一級節(jié)點(diǎn)的集合,第一級節(jié)點(diǎn)的parent等于root。
V. 節(jié)點(diǎn)對象的成員對象:
節(jié)點(diǎn)對象node包含了一些成員對象(屬性),為了方便說明和理解,截了一張圖放大后加上標(biāo)注。如下:
數(shù)字所標(biāo)示的對象依次為:
1.node.exIcon
2.node.icon
3.node.label
4.node.lineIcon[0]
5.node.body
6.node.container
VI. 訪問節(jié)點(diǎn)對象:
1.從上面的示例中我們已經(jīng)看到add方法會返回新添加的節(jié)點(diǎn)對象,將之賦予一個(gè)變量,以后隨時(shí)可以訪問。
2.所有添加的節(jié)點(diǎn)保存在tree.nodes集合數(shù)組中,如對于第一個(gè)添加的節(jié)點(diǎn):
var n0=tree1.add(root,"last","節(jié)點(diǎn)一","node0")
除了n0指向該節(jié)點(diǎn)外,tree.nodes[0]也指向該節(jié)點(diǎn),另外我們還指定了一個(gè)鍵值:"node0",因此tree.nodes["node0"]也指向了該節(jié)點(diǎn),因此n0、tree.nodes[0]和tree.nodes["node0"]引用的都是同一個(gè)對象。
3.執(zhí)行目錄樹節(jié)點(diǎn)遍歷的方法:可以從root.first開始根據(jù)節(jié)點(diǎn)關(guān)系可按多種方法進(jìn)行遍歷,在此不作深究。如果不關(guān)心樹的邏輯結(jié)構(gòu)進(jìn)行遍歷推薦的方法是:
for(var i=1;i<tree.count()-1;i++){tree.nodes[i]}
可能你會想到另一種方法:
for(var i=0;i<tree.nodes.length;i++){tree.nodes[i]}
也是可行的,但要注意如果有節(jié)點(diǎn)設(shè)了鍵值的話,該節(jié)點(diǎn)會被訪問兩次!
4.其它獲得節(jié)點(diǎn)對象的方法:
(1)樹對象的方法:getNodeByPath、getNodeByTier、getSelectNode、getActiveNode
(1)節(jié)點(diǎn)對象的方法: getSibling、節(jié)點(diǎn)關(guān)系(next,first,last,prev,parent,children)
VII. 節(jié)點(diǎn)的操作:
1.刪除節(jié)點(diǎn):node.remove() 或 tree.removeNode(node)
2.子節(jié)點(diǎn)的展開與收縮:
展開:node.expand(true),收縮:node.expand(false),自動(dòng):node.expand()
展開一個(gè)分枝(展開子節(jié)點(diǎn)孫子節(jié)點(diǎn)):node.expand(true,true)
展開所有節(jié)點(diǎn):tree.expandAll(true),收縮所有節(jié)點(diǎn):tree.expandAll(false)
展開至第二層:tree.expandToTier(2)
IX. imagelist控件與目錄樹控件的關(guān)系:
imagelist用于向目錄樹控件提供構(gòu)建目錄樹的各種圖片(圖標(biāo)),在目錄樹控件中這些圖片是如何被使用的呢?在添加節(jié)點(diǎn)的方法中ico參數(shù)是用于設(shè)置節(jié)點(diǎn)圖標(biāo)的,如上例中n1節(jié)點(diǎn)ico為"default",這就是添加節(jié)點(diǎn)時(shí)指定的鍵值,除了用鍵值我們還可以用索引值,因?yàn)?default"是第一個(gè)添加的圖標(biāo)其索引值為0,用0來代替"default"也是可以的??梢娔夸洏淇丶峭ㄟ^鍵值(字符串)或索引值(正整數(shù))來引用imagelist控件中的圖片的。
我們還注意到有些節(jié)點(diǎn)添加時(shí)ico參數(shù)是缺省的,但是該節(jié)點(diǎn)還是有圖標(biāo)顯示的,這就是要談的另一個(gè)議題--約定鍵值。約定鍵值是指imagelist控件中具有這些鍵值的元素在目錄樹控件會有特殊的用途,約定鍵值有以下幾種:
1、default -- 默認(rèn)圖標(biāo),在ico參數(shù)缺省時(shí)節(jié)點(diǎn)使用默認(rèn)圖標(biāo),圖例:
2、expand 和 collapse -- 用于控制子節(jié)點(diǎn)展開和收縮,
常用圖例:
3、expand_top、expand_end、collapse_top、collapse_end,在使用上面第一組圖例時(shí)提供首尾不同的圖片
圖例:
4、leaf 和 twig -- 用于指示樹葉節(jié)點(diǎn)和末稍節(jié)點(diǎn)的圖標(biāo),圖例:
5、line和blank -- 用于畫目錄樹支干連線。圖例: (blank是一張空白的圖片)
6、link -- 特別用于addLink方法,ico參數(shù)缺省時(shí)使用,圖例:
按照這種約定,如果你要顯示控制節(jié)點(diǎn)展開/收縮的圖片,應(yīng)該在向imaglist添加expand和collapse鍵值的圖片,同理要顯示枝干連線就要添加line和blank鍵值的圖片。如果你提供了default圖標(biāo)且添加節(jié)點(diǎn)時(shí)沒有指定的ico參數(shù),default圖標(biāo)就被派上用場了。這是一種非強(qiáng)制的約定,你甚至可以不向imagelist添加任何圖片,這樣你構(gòu)建的就是沒有圖片的樹。正是因?yàn)檫@種約定關(guān)系使得阿賴目錄樹程序擁有超強(qiáng)的靈活性,你可以使用各種的組合,選取各種的圖標(biāo),構(gòu)建出各式各樣的目錄樹來!
XI. 事件處理:
一、事件處理機(jī)制:
樹對象的事件有:onclick , ondblclick , onmousemove , onmouseover , onmouseout , onmouseup , onmousedown , onkeypress , onkeydown , onkeyup , oncollapse , onexpand , afteradd , onblur , onfocus , onselect
節(jié)點(diǎn)對象的事件有:onclick , ondblclick , onmouseover , onmouseout , onmousemove , onmousedown , onmouseup , onkeypress , onkeydown , onkeyup , oncollapse , onexpand , onfocus , onblur , onselect
樹對象的事件用于響應(yīng)所有節(jié)點(diǎn)的相應(yīng)事件,節(jié)點(diǎn)對象是針對個(gè)別的節(jié)點(diǎn)進(jìn)行處理。有一個(gè)很重要的特點(diǎn):樹對象的事件處理程序的第一個(gè)參數(shù)都是引發(fā)該事件的節(jié)點(diǎn)對象,節(jié)點(diǎn)對象的事件均沒有參數(shù)。我們注意到兩者的事件名幾乎相同(tree.afteradd事件例外),對于onclick事件它是這樣執(zhí)行的:當(dāng)鼠標(biāo)點(diǎn)擊節(jié)點(diǎn)時(shí),將會執(zhí)行node.onclick的事件處理程序,如果處理程序返回值為true,接著執(zhí)行tree.onclick事件,反之如果node.onclick的處理程序返回值為false(或沒有返回值),則tree.onclcik事件不會被執(zhí)行。其它事件都是類同于此,這就是事件處理機(jī)制,有點(diǎn)類似DOM(文檔對象模型)的事件冒泡(bubble)。
添加節(jié)點(diǎn)add方法的兩個(gè)參數(shù):exeCategory和exeArgv是用來設(shè)置節(jié)點(diǎn)要執(zhí)行的動(dòng)作,例如:
n1=tree.root.add("test","","js","alert('hello')")
n2=tree.root.add("9499.net","","url","
www.9499.net。如果缺省這兩個(gè)參數(shù)默認(rèn)動(dòng)作是執(zhí)行expand方法展開或收縮子節(jié)點(diǎn)(如果有的話)。單擊節(jié)點(diǎn)執(zhí)行的動(dòng)作實(shí)際上是調(diào)用node.execute()方法,面execute()方法執(zhí)行的動(dòng)作又取決于exeCategory和exeArgv兩個(gè)參數(shù)。node.execute()和onclick事件的聯(lián)系是這樣的:如果tree.onclick事件處理程序返回值為true,將接著調(diào)用node.execute()方法,若返回值為false或無返回值,則node.execute()方法不會被執(zhí)行,這是事件處理機(jī)制的別一個(gè)方面。
二、事件處理程序:
事件處理程序一般用來控制節(jié)點(diǎn)的行為。
示例:如果我們想讓節(jié)點(diǎn)有類似超鏈接的效果,即當(dāng)鼠標(biāo)移過時(shí)文字變藍(lán),加下劃線,但對于節(jié)點(diǎn)n11卻不想讓它如此,可以用下面的事件處理程序?qū)崿F(xiàn):
//鼠標(biāo)移入時(shí)
tree.onmouseover=function(srcNode)
{
srcNode.label.style.color="blue"
srcNode.label.textDecoration="underline"
srcNode.label.cursor="hand"
}
//鼠標(biāo)移出時(shí)
tree.onmouseout=function(srcNode)
{
srcNode.label.style.color="black"
srcNode.label.textDecoration="none"
}
//對節(jié)點(diǎn)11特別處理
n11.onmouseover=n11.onmouseout=function(){return false}
另外點(diǎn)擊節(jié)點(diǎn)時(shí)默認(rèn)動(dòng)作是讓節(jié)點(diǎn)獲得焦點(diǎn)選擇加亮顯示,如果不想讓節(jié)點(diǎn)被選擇可以讓tree.onselect事件處理程序返回值為false,就可以屏蔽這個(gè)行為,如下:
tree.onselect=function(srcNode){return false}
XII.使用模板程序:
目錄樹控件程序具有設(shè)計(jì)多樣化樹狀菜單的能力,為了更方便廣大使用者,我們將一些設(shè)計(jì)好的菜單封裝成模板程序,這樣用戶就可以順手拈來,省去樣式設(shè)計(jì)的麻煩。模板程序?yàn)槲覀冞x好了使用的圖片,設(shè)計(jì)了一些基本的事件處理程序,用戶只須寫添加節(jié)點(diǎn)的代碼就行了,可謂快速高效,多快好?。≡谑纠壳疤峁┝巳缦聨追N常用的模板程序,(以后會有更多更酷的!):
alai_tree_win2k.js -- win2000 explorer風(fēng)格模板
alai_tree_winxp.js -- winxp explorer風(fēng)格模板
alai_tree_help.js -- chm幫助風(fēng)格模板
alai_tree_pretty.js -- 一個(gè)很靚的目錄樹模板
alai_tree_qq.js -- QQ面板模板
alai_tree_cool.js -- COOL面板模板 (真的很酷)
現(xiàn)在我們以win2k模板為例,說明模板程序的使用:
一、首先加載控件程序和模板程序到網(wǎng)頁,代碼:
<script src="alai_tree.js" language="JScript"></sript>
<script src="alai_tree_win2k.js" language="JScript"></sript>
二、調(diào)用模板,添加節(jié)點(diǎn):
//實(shí)例化目錄樹模板程序,將返回一個(gè)樹對象。
var tree2=new alai_tree_win2k(divTree) //divTree是目錄樹放置的地方,如果缺省目錄樹會放到網(wǎng)頁的最前面。
tree2.root.add("節(jié)點(diǎn)一")
tree2.root.add("節(jié)點(diǎn)二")
看,用這樣的方法建目錄樹多省事??!其實(shí)這些模板程序并不復(fù)雜,你可以研究一下這些程序然后DIY出屬于自己的模板,做出來別忘了跟我分享你的成果!
XIII. 目錄樹控件功能擴(kuò)展:
目錄樹控件的功能到目前為止已經(jīng)相當(dāng)完美,相信你在網(wǎng)上找不到比這功能更強(qiáng)大的目錄樹程序了,但是它的功能還是不止于此,我們可以根據(jù)需要擴(kuò)充它的功能。alai_tree_check.js是目前提供的一個(gè)擴(kuò)展程序,加載目錄樹程序后再加載alai_tree_check,目錄樹控件就會增加具有添加多選按扭checkbox的節(jié)點(diǎn)的功能。加載alai_tree_check后目錄樹將增加如下成員對象:
tree.addChkNode(toNode,text,ico,exeCategory,exeArg,checked) 方法添加具有checkbox的節(jié)點(diǎn)(參數(shù)用途可參考tree.add方法)
tree.colChkNode 屬性,保存具有checkbox的節(jié)點(diǎn)的集合數(shù)組
tree.oncheck 和 node.oncheck事件 點(diǎn)擊checkbox時(shí)觸發(fā)該事件
node.isCheck 屬性,用于判斷節(jié)點(diǎn)是否有checkbox
node.checkBox 屬性,節(jié)點(diǎn)的checkbox對象
下面結(jié)合另一具模板程序pretty的使用來說明該擴(kuò)展程序的使用:
一、首先加載控件程序,模板程序和擴(kuò)展程序到網(wǎng)頁(注意:擴(kuò)展程序的加載一定要置后于控件程序),代碼:
<script src="alai_tree.js" language="JScript"></sript>
<script src="alai_tree_pretty.js" language="JScript"></sript>
<script src="alai_tree_check.js" language="JScript"></sript>
二、調(diào)用模板,添加節(jié)點(diǎn):
var tree3=new alai_tree_pretty(divTree) //divTree是目錄樹放置的地方,如果缺省目錄樹會放到網(wǎng)頁的最前面。
tree3.root.add("節(jié)點(diǎn)一") //添加普通節(jié)點(diǎn)
tree3.addChkNode(tree3.root,"節(jié)點(diǎn)二") //添加有checkbox的節(jié)點(diǎn)