沒想到有這么多的朋友關注的dTree,過幾天在我的新博客http://www.xiaosilent.com再發表一些關于dTree的文章,并會將本文中的例子修正好放出來,和大家互相學習。
由于最近收到不少朋友發來mail反應demo不能運行的問題,在這里再次提請各位看官注意:本文處提供下載的dtree不能直接運行,需要修改其中onreadystatechange 的具體實現? By xiaosilent 2007/11/20
?????? 由于手上的項目要用到目錄樹來顯示分類信息,于是有機會了解了一下常用的目錄樹。Google了一下,結果并不是很多。最后圈定了dTree。因為它的功能不弱,使用也還是很方便的,但是dTree原來是一次性加載的,不能動態添加節點。但是,只要稍作修改,還是可以實現的。
首先來看看 dTree 到底是什么樣的。
從http://www.destroydrop.com/javascripts/tree/下載回dtree.zip,整個壓縮包15K不到,可謂是相當苗條的了。解壓開,里面有一個名為img的文件夾,兩個html文件和一個dtree.js以及dtree.css。我們需要關注的是example01.html文件和dtree.js兩個文件。
關于dTree是如何工作的,這點我就不再贅述了。
看 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;

}
;
節點通過其add方法添加到目錄樹,而目錄樹是通過調用其 toString() 輸出到頁面,所有節點數據都保存在一個名為aNodes的數組里,隨著程序的運行,數組里的數據會隨之而發生變化,然而,要實現動態添加節點,就必須要保持原有的數據不變,這點,我們可以通過再添加一個數組來解決。讓 add方法把數據添加到一個數組里,并讓該數組的數據保持不變。而在toString方法里可以看到對addNode方法的調用,我們通過對該方法的修改,讓其操縱另外的一個數組而不是add方法添加數據的那個。然后,再添加一個新方法,在該方法里完成將add方法操縱的數組內數據復制到另一數組的操作。修改toString方法,讓其獲取一個容器,并把str寫入該容器。再添加一個getChildren方法,用來獲取一個節點的子節點,并根據該節點是否有子節點而變化其圖標。
修改后的 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("創建Microsoft.XMLHTTP對象失敗,AJAX不能正常運行.請檢查您的瀏覽器設置.");
????????}
????????

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

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

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

????????????}catch(e)
{
????????????
????????????????alert("創建XMLHttpRequest對象失敗,AJAX不能正常運行.請檢查您的瀏覽器設置.");
????????????}
????????????
????????}
????}
????
????//?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+")",?"點擊獲取其子類",'',tree.icon.folder);
????????????????????????

????????????????????}else
{
????????????????????????
????????????????????????tree.aNodesData[tree.aNodesData.length]=new?Node(id,?pid,?name,?"javascript:"+tree.obj+".showCategory("+id+")",?"點擊獲取詳請");
????????????????????????
????????????????????}
????????????????}
????????????}
????????????
????????????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.

};最后,客戶端可以通過以下方式調用
<div?class="dtree"?id="dtree1">


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

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

????????d.add(0,-1,'點擊展開商品分類信息',"javascript:d.getChildren(0)");
????????
????????d.show();


????</script>

</div>甚至可以在同一個頁面里同時存在多個的tree,只要指定不同的容器,和創建不同的dtree對象即可。如:
<div?class="dtree"?id="dtree2">


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

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

????????w.add(0,-1,'點擊展開客戶分類信息',"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,'點擊展開商家分類信息',"javascript:z.getChildren(0)");
????????
????????z.show();


????</script>

</div>這樣,雖然實現了節點的動態添加,但是,由于每次都要復制一次數組,程序執行的效率不高,期待更好的實現。
示例下載?需要有服務器提供正確的返回值才能正常運行……
posted on 2007-04-28 16:54
xiaosilent 閱讀(17594)
評論(17) 編輯 收藏 所屬分類:
Java相關