dtree详细资料

dtree详细资料

标签: javascriptclasscookiesdivhtmlstylesheet
分类:
第三方工具、 插件的使用 (16)

作者:diaoyf  |  文章来源:http://programmerdigest.cn

dTree是一个免费的JavaScript树形菜单,使用简单,界面制作的也很专业。

dtree树形菜单

dtree树形菜单

所谓“兵无常势,水无常形”,不同的项目需求,造成菜单树的各种变化,因此在介绍dTree的同时,本文着重讲述如何改造dTree,以达到为不同项目所用的目的。

 

dTree 分析

dTree的使用非常简单,在下载的dTree压缩文件中(2.05),要用的只有三个:

1. dtree.js : dtree功能脚本
2. dtree.css : 样式文件
3. img文件夹 : 存放dtree使用的图标,参看下图:

dtree图标

dtree图标

很容易就可以编写出类似上面的dtree菜单树,源代码如下:

  1. <html>
  2. <head>
  3. <link rel="StyleSheet" href="dtree.css" type="text/css" />
  4. <script type="text/javascript" src="dtree.js"></script>
  5. </head>
  6. <body>
  7. <script type= "text/javascript">
  8. <!–
  9. d = new dTree(‘d’); //创建树,名称为’d'(注意和树的对象变量名称要一致)
  10. d. add(0,-1,‘My example tree’); //在树中增加节点。节点id是0,父节点是-1(根节点),节点文字’My example tree’
  11. d. add(1,0,‘Node 1′,‘default.html’); //根节点的子节点(父节点是0),’default.html’表示节点链接(鼠标点击页面跳转url)
  12. d. add(2,0,‘Node 2′,‘default.html’);
  13. d. add(3,1,‘Node 1.1′,‘default.html’);
  14. d. add(4,0,‘Node 3′,‘default.html’);
  15. d. add(5,3,‘Node 1.1.1′,‘default.html’);
  16. d. add(6,5,‘Node 1.1.1.1′,‘default.html’);
  17. d. add(7,0,‘Node 4′,‘default.html’);
  18. d. add(8,1,‘Node 1.2′,‘default.html’);
  19. d. add(9,0,‘My Pictures’,‘default.html’,‘Pictures I/’ve taken over the years’,”,”,‘img/imgfolder.gif’); //’Pictures I/’ve taken over the years’是链接title,指定图标
  20. d. add(10,9,‘The trip to Iceland’,‘default.html’,‘Pictures of Gullfoss and Geysir’);
  21. d. add(11,9,‘Mom/’s birthday’,‘default.html’);
  22. d. add(12,0,‘Recycle Bin’,‘default.html’,”,”,‘img/trash.gif’);
  23. document. write(d); //输出dtree的html(显示)
  24. //–>
  25. </script>
  26. </body>
  27. </html>

分析dtree.js,在dTree中只有两个结构:”节点”和”树”,dTree的所有功能和构造都在于这两个结构的属性和行为中,Node比较简单,只包含节点的基本属性和一个构造方法,所以对dTree的分析和研究的重点可放在dTree结构中。

<!--#uml-class{width:450px;background:#FFFFCE;border-collapse:collapse;}#uml-class th{border:1px solid #000;font-size:14pt;}#uml-class td{border:1px solid #000;font-size:10pt;}#uml-class td ul{list-style-type:circle;}#uml-class td ul li{margin:0px 0px 0px -10px;font-family:Monospace;}#uml-class td ul li a{text-decoration:none;color:#000;}#uml-class td ul li a:hover{border-bottom:1px dotted;}#uml-class td ul li span{display:none;color:#666;border:1px dotted #000;}-->

 

Node
Attributes(属性)
Operations(行为)

节点类图

dTree
Attributes(属性)
  • obj : String树的名称,在创建树时定义。
  • aNodes : Node[]树中的节点数组。
  • aIndent : []数组。
  • root : Node根节点。
  • selectedNode : Node当前选择的节点。
  • selectedFound : boolean是否有选中节点,默认false。
  • completed : boolean树构建html是否已完成完成,默认false。
  • config : Hash数组树的配置
    • target: 设置所有节点的target,默认null
    • folderLinks: 目录节点是否可以有链接,默认true
    • useSelection: 节点是否可以被选择(高亮),默认true
    • useCookies: 设置使用cookies保存树的状态,默认true
    • useLines: 是否显示路径点线,默认true
    • useIcons: 是否显示图标,默认true
    • useStatusText: 是否在状态栏输出节点文字(替换原来的url显示),默认false
    • closeSameLevel: 是否自动关闭兄弟节点(当打开本节点时),注意设置true时,openAll()和closeAll()不能工作,默认false
    • inOrder: 如果父节点总是在子节点之前加入树,设置true有更好的效率,默认false
  • icon : Hash数组图标
    • root: 根,默认'img/base.gif'
    • folder: 关闭的文件夹,默认'img/folder.gif'
    • folderOpen: 打开的文件夹,默认'img/folderOpen.gif'
    • node: 文件,默认'img/page.gif'
    • empty: 空,默认'img/empty.gif'
    • line: 竖线,默认'img/line.gif'
    • join: 丁线,默认'img/join.gif'
    • joinBottom: 直角线,默认'img/joinbottom.gif'
    • plus: 加号丁线,默认'img/plus.gif'
    • plusBottom: 加号直角线,默认'img/plusbottom.gif'
    • minus: 减号丁线,默认'img/minus.gif'
    • minusBottom: 减号直角线,默认'img/minusbottom.gif'
    • nlPlus: 无线加号,默认'img/nolines_plus.gif'
    • nlMinus: 无线减号,默认'img/nolines_minus.gif'
Operations(行为)

树类图

提示:
鼠标移动到类图中的属性或方法上时,会显示详细信息。

dTree的工作原理

类似dTree这样的动态的客户端web插件,实现起来基本离不开xhtml和javascript,用一段简单的代码来探索一下dTree的工作原理:

  1. <html>
  2. <head>
  3. <link rel="StyleSheet" href="dtree.css" type="text/css" />
  4. <script type="text/javascript" src="dtree.js"></script>
  5. </head>
  6. <body>
  7. <script type= "text/javascript">
  8. <!--
  9. d = new dTree('d'); //创建树,名称为'd'
  10. d. add(0,-1,'根节点');
  11. d. add(1,0,'节点 1','node1.html');
  12. d. add(2,0,'节点 2','node2.html');
  13. d. add(3,1,'节点 1.1','node1_1.html');
  14. d. add(4,3,'节点 1.1.1','node1_1_1.html');
  15. document. write(d);
  16.  
  17. function show()
  18. {
  19.     alert(d);
  20. }
  21. //-->
  22. </script>
  23.  
  24. <input type="button" value="显示html" οnclick="show()">
  25. </body>
  26. </html>

显示的“树”如下图:

dtree02

点击下方的“显示html”按钮,会在alert对话框中显示整个树的html代码,整理后如下:

  1. <div class="dtree">
  2.     <div class="dTreeNode">
  3.         <img id="id0" src="img/base.gif" alt="" />根节点</a>
  4.     </div>
  5.     <div id="dd0" class="clip" style="display:block;">
  6.         <div class="dTreeNode">
  7.             <a href="javascript: d.o(1);"><img id="jd1" src="img/minus.gif" alt="" /></a>
  8.             <img id="id1" src="img/folderopen.gif" alt="" />
  9.             <a href="javascript: d.o(1);" class="node">节点 1</a>
  10.         </div>
  11.         <div id="dd1" class="clip" style="display:block;">
  12.             <div class="dTreeNode">
  13.                 <img src="img/line.gif" alt="" />
  14.                 <a href="javascript: d.o(3);"><img id="jd3" src="img/minusbottom.gif" alt="" /></a>
  15.                 <img id="id3" src="img/folderopen.gif" alt="" />
  16.                 <a href="javascript: d.o(3);" class="node">节点 1.1</a>
  17.             </div>
  18.             <div id="dd3" class="clip" style="display:block;">
  19.                 <div class="dTreeNode">
  20.                     <img src="img/line.gif" alt="" />
  21.                     <img src="img/empty.gif" alt="" />
  22.                     <img src="img/joinbottom.gif" alt="" />
  23.                     <img id="id4" src="img/page.gif" alt="" />
  24.                     <a id="sd4" class="node" href="node1_1_1.html" οnclick="javascript: d.s(4);">节点 1.1.1</a>
  25.                 </div>
  26.             </div>
  27.         </div>
  28.         <div class="dTreeNode">
  29.             <img src="img/joinbottom.gif" alt="" />
  30.             <img id="id2" src="img/page.gif" alt="" />
  31.             <a id="sd2" class="node" href="node2.html" οnclick="javascript: d.s(2);">节点 2</a>
  32.         </div>
  33.     </div>
  34. </div>

仔细观察,树中每个节点的html构造是相似的:

  1. <!-- 根节点 -->
  2. <div class="dTreeNode">
  3.     <img id="id0" src="img/base.gif" alt="" />根节点</a>
  4. </div>
  5. <div id="dd0" class="clip" style="display:block;">
  6.     ......
  7. </div>
  1. <!-- 节点 1 -->
  2. <div class="dTreeNode">
  3.     <a href="javascript: d.o(1);"><img id="jd1" src="img/minus.gif" alt="" /></a>
  4.     <img id="id1" src="img/folderopen.gif" alt="" />
  5.     <a href="javascript: d.o(1);" class="node">节点 1</a>
  6. </div>
  7. <div id="dd1" class="clip" style="display:block;">
  8.     ......
  9. </div>
  1. <!-- 节点 1.1 -->
  2. <div class="dTreeNode">
  3.     <img src="img/line.gif" alt="" />
  4.     <a href="javascript: d.o(3);"><img id="jd3" src="img/minusbottom.gif" alt="" /></a>
  5.     <img id="id3" src="img/folderopen.gif" alt="" />
  6.     <a href="javascript: d.o(3);" class="node">节点 1.1</a>
  7. </div>
  8. <div id="dd3" class="clip" style="display:block;">
  9.     ......
  10. </div>
  1. <!-- 节点 1.1.1 -->
  2. <div class="dTreeNode">
  3.     <img src="img/line.gif" alt="" />
  4.     <img src="img/empty.gif" alt="" />
  5.     <img src="img/joinbottom.gif" alt="" />
  6.     <img id="id4" src="img/page.gif" alt="" />
  7.     <a id="sd4" class="node" href="node1_1_1.html" οnclick="javascript: d.s(4);">节点 1.1.1</a>
  8. </div>
  1. <!-- 节点 2 -->
  2. <div class="dTreeNode">
  3.     <img src="img/joinbottom.gif" alt="" />
  4.     <img id="id2" src="img/page.gif" alt="" />
  5.     <a id="sd2" class="node" href="node2.html" οnclick="javascript: d.s(2);">节点 2</a>
  6. </div>

每个节点由两个<div>组成,第一个div (class="dTreeNode")描述当前节点,如节点显示文字、节点图标、图标前的加减号、连线等;第二个div (class="clip")描述当前节点的子节点(包括子节点的子节点),注意div的样式 style="display:block;","block"表示显示div,也就是显示子节点,如果样式为 style="display:none;",则隐藏div,也就隐藏了子节点,d.o()函数控制display样式的变换,也就相应实现了子节点的打开和关闭。

"节点 1.1.1" 和 "节点 2" 没有子节点,所以没有第二个<div>。

 

 

 

作者:diaoyf  |  文章来源:http://programmerdigest.cn

在dTree中,树中的节点是一次生成的,但在一些应用场景中,节点数非常大,比如我国的行政区划中省、市县两级的数量就超千个,一次性的生成dTree树非常耗资源,速度也慢。针对这种情况需要“异步”构建树,比如在页面上先生成省、自治区的一级节点,当用鼠标点开某个“省”节点时,实时从后台获得该省下级的市县节点。

下面就一步步的完成这个对dTree的改造需求。

 

改造原则

我在这里要说明的是:不建议对dTree大改,因为改的越多风险越大,毕竟我们只是dTree的使用者,而不是开发者,特别在项目时间紧、压力大的环境中,迅速打造一个能用、稳定的控件尤其重要。

创建一级节点

这里的行政区划不规范,和国家规定的有出入,但作为示例程序比较好理解,从我所在的省份“陕西省”开始,省的下级有“陕北”、“关中”、“陕南”三个子集。

  1. d = new dTree(’d'); //创建树,名称为’d’
  2. d.add(0,-1,’陕西省’);
  3. d.add(1,0,’陕北’);
  4. d.add(2,0,’关中’);
  5. d.add(3,0,’陕南’);
  6. document.write(d);

生成的页面显示:

dtree03

在dTree中,如果一个节点没有子集,它的前面不会出现“+”图标,我们希望在红色标记处形有“+”或“-”图标,这样就可以动态的从后台获取他们的子集。查看d.add()函数的实现代码:

  1. dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) {
  2.     //增加到节点数组的末尾
  3.     this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open);
  4. };

在add函数中,new了一个节点对象,aNodes是dTree中的节点数组,下标“this.aNodes.length”是数组末尾的下一个,表示在数组最后增加一个节点。将上面的代码改动一下:

  1. d = new dTree(’d');
  2. d.add(0,-1,’陕西省’);
  3.  
  4. //陕北
  5. var shanbei = new Node(1,0,’<input type=/"checkbox/" name=/"where/" value=/"1/">陕北’);
  6. shanbei._hc = true; //有子节点
  7. d.aNodes[d.aNodes.length] = shanbei; //加入到树
  8. //关中
  9. var guanzhong = new Node(2,0,’<input type=/"checkbox/" name=/"where/" value=/"2/">关中’);
  10. guanzhong._hc = true;
  11. d.aNodes[d.aNodes.length] = guanzhong;
  12. //陕南
  13. var shannan = new Node(3,0,’<input type=/"checkbox/" name=/"where/" value=/"3/">陕南’);
  14. shannan._hc = true;
  15. d.aNodes[d.aNodes.length] = shannan;
  16.  
  17. document.write(d);

先new出节点对象,将对象的”_hc”属性置为true,表示有子节点,形成的页面显示如下(手工点开了“关中”节点):

dtree04

点击“显示html”按钮,观察一下树的html结构:

  1. <div class="dtree">
  2.     <div class="dTreeNode">
  3.         <img id="id0" src="img/base.gif" alt="" />陕西省</a>
  4.     </div>
  5.     <div id="dd0" class="clip" style="display:block;">
  6.         <div class="dTreeNode">
  7.             <a href="javascript: d.o(1);"><img id="jd1" src="img/plus.gif" alt="" /></a>
  8.             <img id="id1" src="img/folder.gif" alt="" />
  9.             <a href="javascript: d.o(1);" class="node"><input type="checkbox" name="where" value="1">陕北</a>
  10.         </div>
  11.         <div id="dd1" class="clip" style="display:none;"></div>
  12.         <div class="dTreeNode"><a href="javascript: d.o(2);">
  13.             <img id="jd2" src="img/minus.gif" alt="" /></a>
  14.             <img id="id2" src="img/folderopen.gif" alt="" />
  15.             <a href="javascript: d.o(2);" class="node"><input type="checkbox" name="where" value="2">关中</a>
  16.         </div>
  17.         <div id="dd2" class="clip" style="display:block;"></div>
  18.         <div class="dTreeNode">
  19.             <a href="javascript: d.o(3);"><img id="jd3" src="img/plusbottom.gif" alt="" /></a>
  20.             <img id="id3" src="img/folder.gif" alt="" />
  21.             <a href="javascript: d.o(3);" class="node"><input type="checkbox" name="where" value="3">陕南</a>
  22.         </div>
  23.         <div id="dd3" class="clip" style="display:none;"></div>
  24.     </div>
  25. </div>

“关中”有子节点div标签,<div id=”dd2″ class=”clip” style=”display:block;”></div>,但没有内部子节点内容。

动态获取下级节点

节点的打开和关闭是由d.o()函数控制的,下来需要对d.o()函数做点小改动,先观察o函数的原始代码(我加上了注释):

  1. //———————————
  2. // dTree对象的o()方法
  3. // 打开或关闭指定节点
  4. //  参数id: 节点ID
  5. //———————————
  6. dTree.prototype.o = function(id) {
  7.     //id对应的节点对象
  8.     var cn = this.aNodes[id];
  9.     //html变化
  10.     this.nodeStatus(!cn._io, id, cn._ls);
  11.     //open状态反转
  12.     cn._io = !cn._io;
  13.     //关闭同级别节点
  14.     if (this.config.closeSameLevel) this.closeLevel(cn);
  15.     //状态更新保存在cookies
  16.     if (this.config.useCookies) this.updateCookie();
  17. };

下面是改动后的代码:

  1. //———————————
  2. // dTree对象的o()方法
  3. // 打开或关闭指定节点
  4. //  参数id: 节点ID
  5. //———————————
  6. dTree.prototype.o = function(id) {
  7.     //示例程序只处理“关中”的子集
  8.     if (id == 2){
  9.         //子节点标签, “关中”子节点div的id是"dd2"
  10.         var subDIV = document.getElementById("dd" + id);
  11.  
  12.         //判断子节点标签是否有内容,如果没有内容就从“后台”动态获取,
  13.         //如果有内容则跳过,这样只在第一次打开节点时获取“后台”数据。
  14.         if(subDIV != null && !subDIV.hasChildNodes())
  15.         {
  16.             //一般通过Ajax从后台获取子集信息,示例程序省略了。
  17.             //假定从后台获取“关中”的子节点信息为:
  18.             //      有两个子节点:“西安”节点id=5,有子节点;“咸阳”id=6,无子节点(叶子节点)
  19.  
  20.             //构造西安节点
  21.             var xian = new Node(5,id,’<input type=/"checkbox/" name=/"where/" value=/"5/">西 安’);
  22.             xian._hc = true; //有子节点
  23.             this.aNodes[this.aNodes.length] = xian; //加入到树
  24.  
  25.             //构造咸阳节点
  26.             var xianyang = new Node(6,id,’<input type=/"checkbox/" name=/"where/" value=/"6/">咸阳’);
  27.             xianyang._hc = false; //无子节点
  28.             this.aNodes[this.aNodes.length] = xianyang; //加入到树
  29.         }
  30.     }
  31.  
  32.     //id对应的节点对象
  33.     var cn = this.aNodes[id];
  34.     //html变化
  35.     this.nodeStatus(!cn._io, id, cn._ls);
  36.     //open状态反转
  37.     cn._io = !cn._io;
  38.     //关闭同级别节点
  39.     if (this.config.closeSameLevel) this.closeLevel(cn);
  40.     //状态更新保存在cookies
  41.     if (this.config.useCookies) this.updateCookie();
  42. };

o函数中增加的的代码模拟了从后台获得“关中”子节点,在一般的应用中通常是通过Ajax技术来获取动态内容,Ajax的实现种类很多,所以这里只模拟而不演示具体的。

不论从后台通过何种技术来动态获取,获取信息必须要包括:

1. 子节点的ID
2. 子节点的名称
3. 子节点是否有下级

20-28行,根据从“后台”获得的子节点信息,在树中添加“西安”和“咸阳”两个节点,但遗憾的是,点开“关中”节点时并没有出现预想的状况,和o函数修改前没什么变化。

同步更新DOM

点击“显示html”按钮,在alret对话框中“关中”子节点的<div>中已经出现了“西安”和“咸阳”的标签代码,页面不响应是因为dTree的实现是基于html的,而不是基于DOM的,当语句 document.write(d); 将树html输出给浏览器后,再去改变”d”的内容,浏览器是不响应的,要达到我们的目的,需要一点技巧:

  1. <html>
  2. <head>
  3. <link rel="StyleSheet" href="dtree.css" type="text/css" />
  4. <script type="text/javascript" src="dtree.js"></script>
  5. <script type= "text/javascript">
  6. <!–
  7. function show()
  8. {
  9.     alert(d.toString());
  10. }
  11. //–>
  12. </script>
  13. </head>
  14. <body>
  15. <div id="mydTree">
  16. <script type= "text/javascript">
  17. <!–
  18. d = new dTree(‘d’);
  19. d. add(0,-1,‘陕西省’,null,null,null,‘img/globe.gif’);
  20.  
  21. //陕北
  22. var shanbei = new Node(1,0,‘<input type=/”checkbox/” name=/”where/” value=/”1/”>陕北’);
  23. shanbei._hc = true; //有子节点
  24. d. aNodes[d.aNodes.length] = shanbei; //加入到树
  25. //关中
  26. var guanzhong = new Node(2,0,‘<input type=/”checkbox/” name=/”where/” value=/”2/”>关中’);
  27. guanzhong._hc = true;
  28. d. aNodes[d.aNodes.length] = guanzhong;
  29. //陕南
  30. var shannan = new Node(3,0,‘<input type=/”checkbox/” name=/”where/” value=/”3/”>陕南’);
  31. shannan._hc = true;
  32. d. aNodes[d.aNodes.length] = shannan;
  33.  
  34. document. write(d);
  35.  
  36. //–>
  37. </script>
  38. </div>
  39.  
  40. <input type="button" value="显示html" οnclick="show()">
  41. </body>

在dTree输出的外面包了一层div标签,就是那个 id=”mydTree” 的div标签,然后在o函数中增加一句:

  1.             ……
  2.             //构造咸阳节点
  3.             var xianyang = new Node(6,id,’<input type=/"checkbox/" name=/"where/" value=/"6/">咸阳’);
  4.             xianyang._hc = false; //无子节点
  5.             this.aNodes[this.aNodes.length] = xianyang; //加入到树
  6.            
  7.             //同步修改DOM
  8.             document.getElementById("mydTree").innerHTML = this.toString();
  9.         }
  10.     }
  11.  
  12.     //id对应的节点对象
  13.  
  14.     var cn = this.aNodes[id];
  15.     ……
  16.  

至此,完成“异步”dTree树的改造,页面显示效果如下:

dtree05


以上代码,通过了Firefox3.5和IE8.0的测试

 

 

 

原文的网址见:http://programmerdigest.cn/2009/12/607.html

 

 
1
0
 
 
 
 

参考知识库

img

JavaScript知识库

15111关注|1516收录

img

软件测试知识库

4779关注|318收录

img

jQuery知识库

9238关注|948收录

img

AngularJS知识库

4945关注|569收录

猜你在找
 
关闭
查看评论
2楼 lq421102 2010-10-23 20:34发表 [回复]
很详细 真心感谢!
1楼 ScarStone 2010-10-20 14:38发表 [回复]
[e01]在么??请问当选中后 单击改成双击怎么改啊!!!??急!!谢啦!
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
 
 
 
 
  • 个人资料
 
 
    • 访问:410474次
    • 积分:5064
    • 等级:
    • 排名:第4962名
    • 原创:134篇
    • 转载:47篇
    • 译文:0篇
    • 评论:42条
 
  • 最新评论
 
 
 
 


标签: javascriptclasscookiesdivhtmlstylesheet
分类:
第三方工具、 插件的使用 (16)

作者:diaoyf  |  文章来源:http://programmerdigest.cn

dTree是一个免费的JavaScript树形菜单,使用简单,界面制作的也很专业。

dtree树形菜单

dtree树形菜单

所谓“兵无常势,水无常形”,不同的项目需求,造成菜单树的各种变化,因此在介绍dTree的同时,本文着重讲述如何改造dTree,以达到为不同项目所用的目的。

 

dTree 分析

dTree的使用非常简单,在下载的dTree压缩文件中(2.05),要用的只有三个:

1. dtree.js : dtree功能脚本
2. dtree.css : 样式文件
3. img文件夹 : 存放dtree使用的图标,参看下图:

dtree图标

dtree图标

很容易就可以编写出类似上面的dtree菜单树,源代码如下:

  1. <html>
  2. <head>
  3. <link rel="StyleSheet" href="dtree.css" type="text/css" />
  4. <script type="text/javascript" src="dtree.js"></script>
  5. </head>
  6. <body>
  7. <script type= "text/javascript">
  8. <!–
  9. d = new dTree(‘d’); //创建树,名称为’d'(注意和树的对象变量名称要一致)
  10. d. add(0,-1,‘My example tree’); //在树中增加节点。节点id是0,父节点是-1(根节点),节点文字’My example tree’
  11. d. add(1,0,‘Node 1′,‘default.html’); //根节点的子节点(父节点是0),’default.html’表示节点链接(鼠标点击页面跳转url)
  12. d. add(2,0,‘Node 2′,‘default.html’);
  13. d. add(3,1,‘Node 1.1′,‘default.html’);
  14. d. add(4,0,‘Node 3′,‘default.html’);
  15. d. add(5,3,‘Node 1.1.1′,‘default.html’);
  16. d. add(6,5,‘Node 1.1.1.1′,‘default.html’);
  17. d. add(7,0,‘Node 4′,‘default.html’);
  18. d. add(8,1,‘Node 1.2′,‘default.html’);
  19. d. add(9,0,‘My Pictures’,‘default.html’,‘Pictures I/’ve taken over the years’,”,”,‘img/imgfolder.gif’); //’Pictures I/’ve taken over the years’是链接title,指定图标
  20. d. add(10,9,‘The trip to Iceland’,‘default.html’,‘Pictures of Gullfoss and Geysir’);
  21. d. add(11,9,‘Mom/’s birthday’,‘default.html’);
  22. d. add(12,0,‘Recycle Bin’,‘default.html’,”,”,‘img/trash.gif’);
  23. document. write(d); //输出dtree的html(显示)
  24. //–>
  25. </script>
  26. </body>
  27. </html>

分析dtree.js,在dTree中只有两个结构:”节点”和”树”,dTree的所有功能和构造都在于这两个结构的属性和行为中,Node比较简单,只包含节点的基本属性和一个构造方法,所以对dTree的分析和研究的重点可放在dTree结构中。

<!--#uml-class{width:450px;background:#FFFFCE;border-collapse:collapse;}#uml-class th{border:1px solid #000;font-size:14pt;}#uml-class td{border:1px solid #000;font-size:10pt;}#uml-class td ul{list-style-type:circle;}#uml-class td ul li{margin:0px 0px 0px -10px;font-family:Monospace;}#uml-class td ul li a{text-decoration:none;color:#000;}#uml-class td ul li a:hover{border-bottom:1px dotted;}#uml-class td ul li span{display:none;color:#666;border:1px dotted #000;}-->

 

Node
Attributes(属性)
Operations(行为)

节点类图

dTree
Attributes(属性)
  • obj : String树的名称,在创建树时定义。
  • aNodes : Node[]树中的节点数组。
  • aIndent : []数组。
  • root : Node根节点。
  • selectedNode : Node当前选择的节点。
  • selectedFound : boolean是否有选中节点,默认false。
  • completed : boolean树构建html是否已完成完成,默认false。
  • config : Hash数组树的配置
    • target: 设置所有节点的target,默认null
    • folderLinks: 目录节点是否可以有链接,默认true
    • useSelection: 节点是否可以被选择(高亮),默认true
    • useCookies: 设置使用cookies保存树的状态,默认true
    • useLines: 是否显示路径点线,默认true
    • useIcons: 是否显示图标,默认true
    • useStatusText: 是否在状态栏输出节点文字(替换原来的url显示),默认false
    • closeSameLevel: 是否自动关闭兄弟节点(当打开本节点时),注意设置true时,openAll()和closeAll()不能工作,默认false
    • inOrder: 如果父节点总是在子节点之前加入树,设置true有更好的效率,默认false
  • icon : Hash数组图标
    • root: 根,默认'img/base.gif'
    • folder: 关闭的文件夹,默认'img/folder.gif'
    • folderOpen: 打开的文件夹,默认'img/folderOpen.gif'
    • node: 文件,默认'img/page.gif'
    • empty: 空,默认'img/empty.gif'
    • line: 竖线,默认'img/line.gif'
    • join: 丁线,默认'img/join.gif'
    • joinBottom: 直角线,默认'img/joinbottom.gif'
    • plus: 加号丁线,默认'img/plus.gif'
    • plusBottom: 加号直角线,默认'img/plusbottom.gif'
    • minus: 减号丁线,默认'img/minus.gif'
    • minusBottom: 减号直角线,默认'img/minusbottom.gif'
    • nlPlus: 无线加号,默认'img/nolines_plus.gif'
    • nlMinus: 无线减号,默认'img/nolines_minus.gif'
Operations(行为)

树类图

提示:
鼠标移动到类图中的属性或方法上时,会显示详细信息。

dTree的工作原理

类似dTree这样的动态的客户端web插件,实现起来基本离不开xhtml和javascript,用一段简单的代码来探索一下dTree的工作原理:

  1. <html>
  2. <head>
  3. <link rel="StyleSheet" href="dtree.css" type="text/css" />
  4. <script type="text/javascript" src="dtree.js"></script>
  5. </head>
  6. <body>
  7. <script type= "text/javascript">
  8. <!--
  9. d = new dTree('d'); //创建树,名称为'd'
  10. d. add(0,-1,'根节点');
  11. d. add(1,0,'节点 1','node1.html');
  12. d. add(2,0,'节点 2','node2.html');
  13. d. add(3,1,'节点 1.1','node1_1.html');
  14. d. add(4,3,'节点 1.1.1','node1_1_1.html');
  15. document. write(d);
  16.  
  17. function show()
  18. {
  19.     alert(d);
  20. }
  21. //-->
  22. </script>
  23.  
  24. <input type="button" value="显示html" οnclick="show()">
  25. </body>
  26. </html>

显示的“树”如下图:

dtree02

点击下方的“显示html”按钮,会在alert对话框中显示整个树的html代码,整理后如下:

  1. <div class="dtree">
  2.     <div class="dTreeNode">
  3.         <img id="id0" src="img/base.gif" alt="" />根节点</a>
  4.     </div>
  5.     <div id="dd0" class="clip" style="display:block;">
  6.         <div class="dTreeNode">
  7.             <a href="javascript: d.o(1);"><img id="jd1" src="img/minus.gif" alt="" /></a>
  8.             <img id="id1" src="img/folderopen.gif" alt="" />
  9.             <a href="javascript: d.o(1);" class="node">节点 1</a>
  10.         </div>
  11.         <div id="dd1" class="clip" style="display:block;">
  12.             <div class="dTreeNode">
  13.                 <img src="img/line.gif" alt="" />
  14.                 <a href="javascript: d.o(3);"><img id="jd3" src="img/minusbottom.gif" alt="" /></a>
  15.                 <img id="id3" src="img/folderopen.gif" alt="" />
  16.                 <a href="javascript: d.o(3);" class="node">节点 1.1</a>
  17.             </div>
  18.             <div id="dd3" class="clip" style="display:block;">
  19.                 <div class="dTreeNode">
  20.                     <img src="img/line.gif" alt="" />
  21.                     <img src="img/empty.gif" alt="" />
  22.                     <img src="img/joinbottom.gif" alt="" />
  23.                     <img id="id4" src="img/page.gif" alt="" />
  24.                     <a id="sd4" class="node" href="node1_1_1.html" οnclick="javascript: d.s(4);">节点 1.1.1</a>
  25.                 </div>
  26.             </div>
  27.         </div>
  28.         <div class="dTreeNode">
  29.             <img src="img/joinbottom.gif" alt="" />
  30.             <img id="id2" src="img/page.gif" alt="" />
  31.             <a id="sd2" class="node" href="node2.html" οnclick="javascript: d.s(2);">节点 2</a>
  32.         </div>
  33.     </div>
  34. </div>

仔细观察,树中每个节点的html构造是相似的:

  1. <!-- 根节点 -->
  2. <div class="dTreeNode">
  3.     <img id="id0" src="img/base.gif" alt="" />根节点</a>
  4. </div>
  5. <div id="dd0" class="clip" style="display:block;">
  6.     ......
  7. </div>
  1. <!-- 节点 1 -->
  2. <div class="dTreeNode">
  3.     <a href="javascript: d.o(1);"><img id="jd1" src="img/minus.gif" alt="" /></a>
  4.     <img id="id1" src="img/folderopen.gif" alt="" />
  5.     <a href="javascript: d.o(1);" class="node">节点 1</a>
  6. </div>
  7. <div id="dd1" class="clip" style="display:block;">
  8.     ......
  9. </div>
  1. <!-- 节点 1.1 -->
  2. <div class="dTreeNode">
  3.     <img src="img/line.gif" alt="" />
  4.     <a href="javascript: d.o(3);"><img id="jd3" src="img/minusbottom.gif" alt="" /></a>
  5.     <img id="id3" src="img/folderopen.gif" alt="" />
  6.     <a href="javascript: d.o(3);" class="node">节点 1.1</a>
  7. </div>
  8. <div id="dd3" class="clip" style="display:block;">
  9.     ......
  10. </div>
  1. <!-- 节点 1.1.1 -->
  2. <div class="dTreeNode">
  3.     <img src="img/line.gif" alt="" />
  4.     <img src="img/empty.gif" alt="" />
  5.     <img src="img/joinbottom.gif" alt="" />
  6.     <img id="id4" src="img/page.gif" alt="" />
  7.     <a id="sd4" class="node" href="node1_1_1.html" οnclick="javascript: d.s(4);">节点 1.1.1</a>
  8. </div>
  1. <!-- 节点 2 -->
  2. <div class="dTreeNode">
  3.     <img src="img/joinbottom.gif" alt="" />
  4.     <img id="id2" src="img/page.gif" alt="" />
  5.     <a id="sd2" class="node" href="node2.html" οnclick="javascript: d.s(2);">节点 2</a>
  6. </div>

每个节点由两个<div>组成,第一个div (class="dTreeNode")描述当前节点,如节点显示文字、节点图标、图标前的加减号、连线等;第二个div (class="clip")描述当前节点的子节点(包括子节点的子节点),注意div的样式 style="display:block;","block"表示显示div,也就是显示子节点,如果样式为 style="display:none;",则隐藏div,也就隐藏了子节点,d.o()函数控制display样式的变换,也就相应实现了子节点的打开和关闭。

"节点 1.1.1" 和 "节点 2" 没有子节点,所以没有第二个<div>。

 

 

 

作者:diaoyf  |  文章来源:http://programmerdigest.cn

在dTree中,树中的节点是一次生成的,但在一些应用场景中,节点数非常大,比如我国的行政区划中省、市县两级的数量就超千个,一次性的生成dTree树非常耗资源,速度也慢。针对这种情况需要“异步”构建树,比如在页面上先生成省、自治区的一级节点,当用鼠标点开某个“省”节点时,实时从后台获得该省下级的市县节点。

下面就一步步的完成这个对dTree的改造需求。

 

改造原则

我在这里要说明的是:不建议对dTree大改,因为改的越多风险越大,毕竟我们只是dTree的使用者,而不是开发者,特别在项目时间紧、压力大的环境中,迅速打造一个能用、稳定的控件尤其重要。

创建一级节点

这里的行政区划不规范,和国家规定的有出入,但作为示例程序比较好理解,从我所在的省份“陕西省”开始,省的下级有“陕北”、“关中”、“陕南”三个子集。

  1. d = new dTree(’d'); //创建树,名称为’d’
  2. d.add(0,-1,’陕西省’);
  3. d.add(1,0,’陕北’);
  4. d.add(2,0,’关中’);
  5. d.add(3,0,’陕南’);
  6. document.write(d);

生成的页面显示:

dtree03

在dTree中,如果一个节点没有子集,它的前面不会出现“+”图标,我们希望在红色标记处形有“+”或“-”图标,这样就可以动态的从后台获取他们的子集。查看d.add()函数的实现代码:

  1. dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) {
  2.     //增加到节点数组的末尾
  3.     this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open);
  4. };

在add函数中,new了一个节点对象,aNodes是dTree中的节点数组,下标“this.aNodes.length”是数组末尾的下一个,表示在数组最后增加一个节点。将上面的代码改动一下:

  1. d = new dTree(’d');
  2. d.add(0,-1,’陕西省’);
  3.  
  4. //陕北
  5. var shanbei = new Node(1,0,’<input type=/"checkbox/" name=/"where/" value=/"1/">陕北’);
  6. shanbei._hc = true; //有子节点
  7. d.aNodes[d.aNodes.length] = shanbei; //加入到树
  8. //关中
  9. var guanzhong = new Node(2,0,’<input type=/"checkbox/" name=/"where/" value=/"2/">关中’);
  10. guanzhong._hc = true;
  11. d.aNodes[d.aNodes.length] = guanzhong;
  12. //陕南
  13. var shannan = new Node(3,0,’<input type=/"checkbox/" name=/"where/" value=/"3/">陕南’);
  14. shannan._hc = true;
  15. d.aNodes[d.aNodes.length] = shannan;
  16.  
  17. document.write(d);

先new出节点对象,将对象的”_hc”属性置为true,表示有子节点,形成的页面显示如下(手工点开了“关中”节点):

dtree04

点击“显示html”按钮,观察一下树的html结构:

  1. <div class="dtree">
  2.     <div class="dTreeNode">
  3.         <img id="id0" src="img/base.gif" alt="" />陕西省</a>
  4.     </div>
  5.     <div id="dd0" class="clip" style="display:block;">
  6.         <div class="dTreeNode">
  7.             <a href="javascript: d.o(1);"><img id="jd1" src="img/plus.gif" alt="" /></a>
  8.             <img id="id1" src="img/folder.gif" alt="" />
  9.             <a href="javascript: d.o(1);" class="node"><input type="checkbox" name="where" value="1">陕北</a>
  10.         </div>
  11.         <div id="dd1" class="clip" style="display:none;"></div>
  12.         <div class="dTreeNode"><a href="javascript: d.o(2);">
  13.             <img id="jd2" src="img/minus.gif" alt="" /></a>
  14.             <img id="id2" src="img/folderopen.gif" alt="" />
  15.             <a href="javascript: d.o(2);" class="node"><input type="checkbox" name="where" value="2">关中</a>
  16.         </div>
  17.         <div id="dd2" class="clip" style="display:block;"></div>
  18.         <div class="dTreeNode">
  19.             <a href="javascript: d.o(3);"><img id="jd3" src="img/plusbottom.gif" alt="" /></a>
  20.             <img id="id3" src="img/folder.gif" alt="" />
  21.             <a href="javascript: d.o(3);" class="node"><input type="checkbox" name="where" value="3">陕南</a>
  22.         </div>
  23.         <div id="dd3" class="clip" style="display:none;"></div>
  24.     </div>
  25. </div>

“关中”有子节点div标签,<div id=”dd2″ class=”clip” style=”display:block;”></div>,但没有内部子节点内容。

动态获取下级节点

节点的打开和关闭是由d.o()函数控制的,下来需要对d.o()函数做点小改动,先观察o函数的原始代码(我加上了注释):

  1. //———————————
  2. // dTree对象的o()方法
  3. // 打开或关闭指定节点
  4. //  参数id: 节点ID
  5. //———————————
  6. dTree.prototype.o = function(id) {
  7.     //id对应的节点对象
  8.     var cn = this.aNodes[id];
  9.     //html变化
  10.     this.nodeStatus(!cn._io, id, cn._ls);
  11.     //open状态反转
  12.     cn._io = !cn._io;
  13.     //关闭同级别节点
  14.     if (this.config.closeSameLevel) this.closeLevel(cn);
  15.     //状态更新保存在cookies
  16.     if (this.config.useCookies) this.updateCookie();
  17. };

下面是改动后的代码:

  1. //———————————
  2. // dTree对象的o()方法
  3. // 打开或关闭指定节点
  4. //  参数id: 节点ID
  5. //———————————
  6. dTree.prototype.o = function(id) {
  7.     //示例程序只处理“关中”的子集
  8.     if (id == 2){
  9.         //子节点标签, “关中”子节点div的id是"dd2"
  10.         var subDIV = document.getElementById("dd" + id);
  11.  
  12.         //判断子节点标签是否有内容,如果没有内容就从“后台”动态获取,
  13.         //如果有内容则跳过,这样只在第一次打开节点时获取“后台”数据。
  14.         if(subDIV != null && !subDIV.hasChildNodes())
  15.         {
  16.             //一般通过Ajax从后台获取子集信息,示例程序省略了。
  17.             //假定从后台获取“关中”的子节点信息为:
  18.             //      有两个子节点:“西安”节点id=5,有子节点;“咸阳”id=6,无子节点(叶子节点)
  19.  
  20.             //构造西安节点
  21.             var xian = new Node(5,id,’<input type=/"checkbox/" name=/"where/" value=/"5/">西 安’);
  22.             xian._hc = true; //有子节点
  23.             this.aNodes[this.aNodes.length] = xian; //加入到树
  24.  
  25.             //构造咸阳节点
  26.             var xianyang = new Node(6,id,’<input type=/"checkbox/" name=/"where/" value=/"6/">咸阳’);
  27.             xianyang._hc = false; //无子节点
  28.             this.aNodes[this.aNodes.length] = xianyang; //加入到树
  29.         }
  30.     }
  31.  
  32.     //id对应的节点对象
  33.     var cn = this.aNodes[id];
  34.     //html变化
  35.     this.nodeStatus(!cn._io, id, cn._ls);
  36.     //open状态反转
  37.     cn._io = !cn._io;
  38.     //关闭同级别节点
  39.     if (this.config.closeSameLevel) this.closeLevel(cn);
  40.     //状态更新保存在cookies
  41.     if (this.config.useCookies) this.updateCookie();
  42. };

o函数中增加的的代码模拟了从后台获得“关中”子节点,在一般的应用中通常是通过Ajax技术来获取动态内容,Ajax的实现种类很多,所以这里只模拟而不演示具体的。

不论从后台通过何种技术来动态获取,获取信息必须要包括:

1. 子节点的ID
2. 子节点的名称
3. 子节点是否有下级

20-28行,根据从“后台”获得的子节点信息,在树中添加“西安”和“咸阳”两个节点,但遗憾的是,点开“关中”节点时并没有出现预想的状况,和o函数修改前没什么变化。

同步更新DOM

点击“显示html”按钮,在alret对话框中“关中”子节点的<div>中已经出现了“西安”和“咸阳”的标签代码,页面不响应是因为dTree的实现是基于html的,而不是基于DOM的,当语句 document.write(d); 将树html输出给浏览器后,再去改变”d”的内容,浏览器是不响应的,要达到我们的目的,需要一点技巧:

  1. <html>
  2. <head>
  3. <link rel="StyleSheet" href="dtree.css" type="text/css" />
  4. <script type="text/javascript" src="dtree.js"></script>
  5. <script type= "text/javascript">
  6. <!–
  7. function show()
  8. {
  9.     alert(d.toString());
  10. }
  11. //–>
  12. </script>
  13. </head>
  14. <body>
  15. <div id="mydTree">
  16. <script type= "text/javascript">
  17. <!–
  18. d = new dTree(‘d’);
  19. d. add(0,-1,‘陕西省’,null,null,null,‘img/globe.gif’);
  20.  
  21. //陕北
  22. var shanbei = new Node(1,0,‘<input type=/”checkbox/” name=/”where/” value=/”1/”>陕北’);
  23. shanbei._hc = true; //有子节点
  24. d. aNodes[d.aNodes.length] = shanbei; //加入到树
  25. //关中
  26. var guanzhong = new Node(2,0,‘<input type=/”checkbox/” name=/”where/” value=/”2/”>关中’);
  27. guanzhong._hc = true;
  28. d. aNodes[d.aNodes.length] = guanzhong;
  29. //陕南
  30. var shannan = new Node(3,0,‘<input type=/”checkbox/” name=/”where/” value=/”3/”>陕南’);
  31. shannan._hc = true;
  32. d. aNodes[d.aNodes.length] = shannan;
  33.  
  34. document. write(d);
  35.  
  36. //–>
  37. </script>
  38. </div>
  39.  
  40. <input type="button" value="显示html" οnclick="show()">
  41. </body>

在dTree输出的外面包了一层div标签,就是那个 id=”mydTree” 的div标签,然后在o函数中增加一句:

  1.             ……
  2.             //构造咸阳节点
  3.             var xianyang = new Node(6,id,’<input type=/"checkbox/" name=/"where/" value=/"6/">咸阳’);
  4.             xianyang._hc = false; //无子节点
  5.             this.aNodes[this.aNodes.length] = xianyang; //加入到树
  6.            
  7.             //同步修改DOM
  8.             document.getElementById("mydTree").innerHTML = this.toString();
  9.         }
  10.     }
  11.  
  12.     //id对应的节点对象
  13.  
  14.     var cn = this.aNodes[id];
  15.     ……
  16.  

至此,完成“异步”dTree树的改造,页面显示效果如下:

dtree05


以上代码,通过了Firefox3.5和IE8.0的测试

 

 

 

原文的网址见:http://programmerdigest.cn/2009/12/607.html

 

 
1
0
 
 
 
 

参考知识库

img

JavaScript知识库

15111关注|1516收录

img

软件测试知识库

4779关注|318收录

img

jQuery知识库

9238关注|948收录

img

AngularJS知识库

4945关注|569收录

猜你在找
W
 

转载于:https://www.cnblogs.com/pangting/p/6914011.html

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值