您好朋友,感謝您關注xiaosilent,我在blogjava的博客已經停止更新,請訪問http://kuan.fm了解我的最新情況,謝謝!
          隨筆-82  評論-133  文章-0  trackbacks-0

          沒想到有這么多的朋友關注的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 閱讀(17596) 評論(17)  編輯  收藏 所屬分類: Java相關

          評論:
          # re: 修改 dTree , 實現節點的動態添加 2007-04-29 08:52 | 祎恬凡
          把你做出來的東西,代碼共享一下。  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2007-04-29 09:44 | xiaosilent
          已經添加到隨筆尾部……  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2007-07-22 06:47 | huangdeh
          你好,如何實現“需要有服務器提供正確的返回值才能正常運行”?

          謝謝  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2007-08-14 23:30 | dajay
          是的
          我們項目中也用了dtree感覺不錯
          我現在也需要修改
          但是我們項目比較大
          每次都是在服務器端全部生成 推到客戶端
          在壓力測試中 直接承受不了
          我也想修改dtree 所以看到你的
          感覺這個dtree還是不是很適合做動態的 感覺效率太低
          我的想法跟你一樣。我先下了看看
          有好的想法在 留言給你
          你有什么好的想法也可以mail我
          dajay520@sina.com
            回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2007-11-20 16:28 | xiaosilent
          請各位看官注意:本文處提供下載的dtree不能直接運行,需要修改其中onreadystatechange 的具體實現  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2007-11-21 15:09 | somad
          @xiaosilent
          能說一下具體怎么修改嗎?  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2007-11-28 11:23 | xiaosilent
          參考一下原來的onreadystatechange 相信修改起來不難。 問題關鍵還是在于和服務器端返回值進行配合。  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2008-02-29 11:53 | 賴皮熊
          xiaosilent:你太有才了,非常感謝你的文章,我的動態目錄樹在你文章的指導下終于出來了,特此感謝?。。。。。。。。。。。?!  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2008-06-25 15:52 | 馬新良
          tree.aNodesData[tree.aNodesData.length]=new Node(id, pid, name, "javascript:"+tree.obj+".getChildren("+id+")", "點擊獲取其子類",'',tree.icon.folder);
          朋友,你這行有問題 ,原代碼里面你改過dTree 的Node方法嗎?如果沒改,你這里應該 是錯的,如果改了,你該寫出來是怎么改的啊?不過我按著你的方法搞定了,你這一行搞了我好長時間呢。  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加[未登錄] 2008-09-10 11:41 | bill
          @賴皮熊
          到底怎么改啊,能說一下嗎?  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加[未登錄] 2008-09-10 11:47 | bill
          誰能告訴我一下,由于我們的這個項目是在一期的基礎上改造的,這些Dtree不太熟悉,我的郵箱是fanbing1121@163.com  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2008-10-08 16:00 | 藍拖
          QQ:181202585 加我吧~!有些東西想請教您~!  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2008-12-29 13:29 | frog
          有修改. 在add()方式中  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2009-09-27 09:04 | rachael
          想你那樣添加樹了
          也實現了動態獲取節點的方法
          唯一都問題是打開樹獲取節點的時候
          樹失去焦點了
          alert這個節點的id為null
          請問這怎樣解決?  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加[未登錄] 2009-10-18 23:47 | king
          節點多的話,效率很低!!!每次動態獲取后都要重新生成樹!!  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2011-02-19 11:53 | 訪問
          這樣應該只是修改了他的顯示方式,但最終數據還是全部加載了,關鍵還是從數據的動態加載考慮啊  回復  更多評論
            
          # re: 修改 dTree , 實現節點的動態添加 2013-04-27 10:21 | 小東北
          我更據你的給的代碼,怎么在前臺不顯示啊  回復  更多評論
            
          主站蜘蛛池模板: 应城市| 兰溪市| 高安市| 弥勒县| 襄樊市| 嘉峪关市| 沁阳市| 闸北区| 铁岭市| 兴安县| 台山市| 赣州市| 石景山区| 祥云县| 昆山市| 巍山| 新邵县| 宝山区| 九江县| 江城| 洛浦县| 河曲县| 耒阳市| 偏关县| 临朐县| 威信县| 玉田县| 大余县| 思茅市| 英吉沙县| 明水县| 杭州市| 五河县| 金门县| 喜德县| 大渡口区| 拉萨市| 菏泽市| 临邑县| 莲花县| 稷山县|