没想到有这么多的朋友关注的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 阅读(17616) 
评论(17)  编辑  收藏  所属分类: 
Java相关