沒(méi)想到有這么多的朋友關(guān)注的dTree,過(guò)幾天在我的新博客http://www.xiaosilent.com再發(fā)表一些關(guān)于dTree的文章,并會(huì)將本文中的例子修正好放出來(lái),和大家互相學(xué)習(xí)。
由于最近收到不少朋友發(fā)來(lái)mail反應(yīng)demo不能運(yùn)行的問(wèn)題,在這里再次提請(qǐng)各位看官注意:本文處提供下載的dtree不能直接運(yùn)行,需要修改其中onreadystatechange 的具體實(shí)現(xiàn)? By xiaosilent 2007/11/20
?????? 由于手上的項(xiàng)目要用到目錄樹(shù)來(lái)顯示分類(lèi)信息,于是有機(jī)會(huì)了解了一下常用的目錄樹(shù)。Google了一下,結(jié)果并不是很多。最后圈定了dTree。因?yàn)樗墓δ懿蝗酰褂靡策€是很方便的,但是dTree原來(lái)是一次性加載的,不能動(dòng)態(tài)添加節(jié)點(diǎn)。但是,只要稍作修改,還是可以實(shí)現(xiàn)的。
首先來(lái)看看 dTree 到底是什么樣的。
從http://www.destroydrop.com/javascripts/tree/下載回dtree.zip,整個(gè)壓縮包15K不到,可謂是相當(dāng)苗條的了。解壓開(kāi),里面有一個(gè)名為img的文件夾,兩個(gè)html文件和一個(gè)dtree.js以及dtree.css。我們需要關(guān)注的是example01.html文件和dtree.js兩個(gè)文件。
關(guān)于dTree是如何工作的,這點(diǎn)我就不再贅述了。
看 dtree.js 里面的一小段代碼
//
?Adds?a?new?node?to?the?node?array
dTree.prototype.add?
=
?
function
(id,?pid,?name,?url,?title,?target,?icon,?iconOpen,?open)?
{

????
this
.aNodes[
this
.aNodes.length]?
=
?
new
?Node(id,?pid,?name,?url,?title,?target,?icon,?iconOpen,?open);

}
;

//
?Outputs?the?tree?to?the?page
dTree.prototype.toString?
=
?
function
()?
{

????
var
?str?
=
?'
<
div?class
=
"
dtree
"
>
\n';


????
if
?(document.getElementById)?
{

????????
if
?(
this
.config.useCookies)?
this
.selectedNode?
=
?
this
.getSelected();

????????str?
+=
?
this
.addNode(
this
.root);

????}
?
else
?str?
+=
?'Browser?not?supported.';

????str?
+=
?'
</
div
>
';

????
if
?(
!
this
.selectedFound)?
this
.selectedNode?
=
?
null
;

????
this
.completed?
=
?
true
;

????
return
?str;

}
;
節(jié)點(diǎn)通過(guò)其add方法添加到目錄樹(shù),而目錄樹(shù)是通過(guò)調(diào)用其 toString() 輸出到頁(yè)面,所有節(jié)點(diǎn)數(shù)據(jù)都保存在一個(gè)名為aNodes的數(shù)組里,隨著程序的運(yùn)行,數(shù)組里的數(shù)據(jù)會(huì)隨之而發(fā)生變化,然而,要實(shí)現(xiàn)動(dòng)態(tài)添加節(jié)點(diǎn),就必須要保持原有的數(shù)據(jù)不變,這點(diǎn),我們可以通過(guò)再添加一個(gè)數(shù)組來(lái)解決。讓 add方法把數(shù)據(jù)添加到一個(gè)數(shù)組里,并讓該數(shù)組的數(shù)據(jù)保持不變。而在toString方法里可以看到對(duì)addNode方法的調(diào)用,我們通過(guò)對(duì)該方法的修改,讓其操縱另外的一個(gè)數(shù)組而不是add方法添加數(shù)據(jù)的那個(gè)。然后,再添加一個(gè)新方法,在該方法里完成將add方法操縱的數(shù)組內(nèi)數(shù)據(jù)復(fù)制到另一數(shù)組的操作。修改toString方法,讓其獲取一個(gè)容器,并把str寫(xiě)入該容器。再添加一個(gè)getChildren方法,用來(lái)獲取一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn),并根據(jù)該節(jié)點(diǎn)是否有子節(jié)點(diǎn)而變化其圖標(biāo)。
修改后的 dtree.js 如下(僅 修改的部分)

/**//*--------------------------------------------------

????dTree?2.05?|?www.destroydrop.com/javascript/tree/

????Rewrited?by?xiaosilent@gmail.com?,?xiangdingdang.com

????Last?updated?at?2007-4-28?16:32:05

????
---------------------------------------------------*/




/**//**
*?dTree??
*
*?Edited?by?xiaosilent.
*?
*?objName:?name?of?dTree?object?.?Create?your?dTree?object?like?this???tree=new?dTree('tree',*,*);
*?targetID:?the?id?of?your?container,which?you?used?to?display?the?tree
*?type:?which?kind?of?category?are?you?doing?with???It?must?be?one?of?these??"goods"?,?"vendor"?and?"consumer"?
*
*/

function?dTree(objName,targetID,type)?
{
???

????this.config?=?
{
????????
????????target????????????????????:?null,
????????
????????//?xiaosilent?changed?it?to?be?false.
????????folderLinks????????????:?false,

????????useSelection????????:?true,
????????
????????
????????
????????

????}
????????
????//?xiaosilent?changed?this?to?his?own?path.

????this.icon?=?
{
????
????
????
????};
????

????this.obj?=?objName;

????this.aNodes?=?[];
????
????//?add?by?xiaosilent.?
????this.aNodesData=[];????//This?array?save?the?original?data?all?the?time.
????this.targetID=targetID||'dtree';????//?Tree?will?be?displayed?in?this?container.
????this.type=type;????//?Saves?the?type?of?tree??goods/vendor/consumer?
????

????this.aIndent?=?[];

????this.root?=?new?Node(-1);

????this.selectedNode?=?null;

????this.selectedFound?=?false;

????this.completed?=?false;

};


//?Adds?a?new?node?to?the?node?array

dTree.prototype.add?=?function(id,?pid,?name,?url,?title,?target,?icon,?iconOpen,?open)?
{
????
????//?Add?by?xiaosilent.
????this.completed?=?false;
????
????this.aNodesData[this.aNodesData.length]?=?new?Node(id,?pid,?name,?url,?title,?target,?icon,?iconOpen,?open);

};

//?Add?by?xiaosilent?.
//?get?child?nodes?from?web?server?via?AJAX?automatically?
//?pid?:?parentID.

dTree.prototype.getChildren?=?function(pid)
{
????
????var?ajax?=?null;


????if?(window.ActiveXObject)?
{
????

????????try
{
????????
????????????ajax?=?new?ActiveXObject("Microsoft.XMLHTTP");
????????????

????????}catch(e)
{
????????
????????????alert("創(chuàng)建Microsoft.XMLHTTP對(duì)象失敗,AJAX不能正常運(yùn)行.請(qǐng)檢查您的瀏覽器設(shè)置.");
????????}
????????

????}?else?
{
????

????????if?(window.XMLHttpRequest)?
{
????????????

????????????try
{
????????????????
????????????????ajax?=?new?XMLHttpRequest();
????????????????

????????????}catch(e)
{
????????????
????????????????alert("創(chuàng)建XMLHttpRequest對(duì)象失敗,AJAX不能正常運(yùn)行.請(qǐng)檢查您的瀏覽器設(shè)置.");
????????????}
????????????
????????}
????}
????
????//?This?usr?is?just?for?my?Sales?Management?System.?This?responses?id,name,childCount|id,name,childCount
.
????var?url?="/servlet/category?action=getChildren&parentID="?+?pid?+"&type="?+?this.type;
????
????var?tree=this;
????

????ajax.onreadystatechange?=?function?()?
{
????

????????if?(ajax.readyState?==?4&&ajax.status?==?200)?
{
????????????
????????????if(ajax.responseText=="false")?return;
????????????
????????????var?categories=ajax.responseText.split('|');
????????????

????????????for(var?i=0;i<categories.length;i++)
{
????????????
????????????????var?aCat?=?categories[i].split(',');
????????????????

????????????????if(aCat.length==3)
{
????????????????????
????????????????????var?id=aCat[0];
????????????????????var?name=aCat[1];
????????????????????var?childCount=aCat[2];
????????????????????

????????????????????if(childCount>0)
{
????????????????????????
????????????????????????tree.aNodesData[tree.aNodesData.length]=new?Node(id,?pid,?name,?"javascript:"+tree.obj+".getChildren("+id+")",?"點(diǎn)擊獲取其子類(lèi)",'',tree.icon.folder);
????????????????????????

????????????????????}else
{
????????????????????????
????????????????????????tree.aNodesData[tree.aNodesData.length]=new?Node(id,?pid,?name,?"javascript:"+tree.obj+".showCategory("+id+")",?"點(diǎn)擊獲取詳請(qǐng)");
????????????????????????
????????????????????}
????????????????}
????????????}
????????????
????????????tree.show();
????????}
????????
????};
????
????ajax.open("POST",url);
????ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
????ajax.send(null);
????
}

//?Add?by?xiaosilent.
//?Call?to?show?the?tree.

dTree.prototype.show?=?function()
{
????
????//?Renew?the?two?array?to?save?original?data.
????this.aNodes=new?Array();
????this.aIndent=new?Array();

????//?Dump?original?data?to?aNode?array.

????for(var?i=0?;?i<this.aNodesData.length?;?i++)
{
????????
????????var?oneNode=this.aNodesData[i];

????????this.aNodes[i]=new?Node(oneNode.id,oneNode.pid,oneNode.name,oneNode.url,oneNode.title,oneNode.target,oneNode.icon,oneNode.iconOpen,oneNode.open);
????}
????
????this.rewriteHTML();
}



//?Outputs?the?tree?to?the?page?,?callled?by?show()
//?Changed?by?xiaosilent.
//?Renamed?dTree.prototype.toString?to?this.

dTree.prototype.rewriteHTML?=?function()?
{

????var?str?=?'';
????
????//?Added?by?xiaosilent.?
????var?targetDIV;
????targetDIV=document.getElementById(this.targetID);
????

????if(!targetDIV)
{
????????
????????alert('dTree?can\'t?find?your?specified?container?to?show?your?tree.\n\n?Please?check?your?code!');

????????return;
????}
????
????if?(this.config.useCookies)?this.selectedNode?=?this.getSelected();
????
????str?+=?this.addNode(this.root);
????????

????//?Disabled?by?xiaosilent.
????//????str?+=?'</div>';

????if?(!this.selectedFound)?this.selectedNode?=?null;

????this.completed?=?true;

????
????//?Disabled?and?added?by?xiaosilent.
????//return?str;
????targetDIV.innerHTML=str;

};

//?Highlights?the?selected?node


dTree.prototype.s?=?function(id)?
{
????

????if?(!this.config.useSelection)?return;

????var?cn?=?this.aNodes[id];

????if?(cn._hc?&&?!this.config.folderLinks)?return;
????
????//?Disabled?by?xiaosilent.

};最后,客戶(hù)端可以通過(guò)以下方式調(diào)用
<div?class="dtree"?id="dtree1">


????<script?type="text/javascript">

????????d?=?new?dTree('d',"dtree1",'goods');

????????d.add(0,-1,'點(diǎn)擊展開(kāi)商品分類(lèi)信息',"javascript:d.getChildren(0)");
????????
????????d.show();


????</script>

</div>甚至可以在同一個(gè)頁(yè)面里同時(shí)存在多個(gè)的tree,只要指定不同的容器,和創(chuàng)建不同的dtree對(duì)象即可。如:
<div?class="dtree"?id="dtree2">


????<script?type="text/javascript">

????????w?=?new?dTree('w',"dtree2",'consumer');

????????w.add(0,-1,'點(diǎn)擊展開(kāi)客戶(hù)分類(lèi)信息',"javascript:w.getChildren(0)");
????????
????????w.show();


????</script>

</div>

<div?class="dtree"?id="dtree3">


????<script?type="text/javascript">

????????z?=?new?dTree('z',"dtree3",'vendor');

????????z.add(0,-1,'點(diǎn)擊展開(kāi)商家分類(lèi)信息',"javascript:z.getChildren(0)");
????????
????????z.show();


????</script>

</div>這樣,雖然實(shí)現(xiàn)了節(jié)點(diǎn)的動(dòng)態(tài)添加,但是,由于每次都要復(fù)制一次數(shù)組,程序執(zhí)行的效率不高,期待更好的實(shí)現(xiàn)。
示例下載?需要有服務(wù)器提供正確的返回值才能正常運(yùn)行……
posted on 2007-04-28 16:54
xiaosilent 閱讀(17596)
評(píng)論(17) 編輯 收藏 所屬分類(lèi):
Java相關(guān)