您好朋友,感谢您关注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 阅读(17535) 评论(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 | 小东北
我更据你的给的代码,怎么在前台不显示啊  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: