为了在HTML页面中使用树,我写了这几个js文件,参照了国外网站的xTree, 图片也基本是用它的,生成的DOM结构也和它几乎一样,只是代码彻底的不同。
载入文件的图片loading.gif从流行框架ext拷贝而来
这个树的组件主要有:
6个js程序文件
1个css文件
1个images文件夹,内有几张图片
用户自己的数据文件,可以搞成js文件形式,也可以在java程序中写好,传给jsp。
我有复选框。
xTree是在初始化树时,就把DOM结构全部生成,(所以初始化慢,点击节点快)。
xyTree是当点击加号时,生成DOM结构,点击减号就隐藏, 再点击加号时只是简单的去掉隐藏,所有如某个节点下有多个节点, 第一次点击会稍慢些。(所以初始化快,点击节点稍慢,但可接收)
DivTreeNormal
TreeNormal
NodeNormal
DivTree
Tree
Node
在数据js文件中添加节点时必须按顺序,以下代码会产生错误:
node1 = new xyTree.Node('下关分局'); node1.id = 1; tree1.add(node1); node222 = new xyTree.Node('玄武分局'); node222.id = 3; tree1.add(node222); node2 = new xyTree.Node('下关派出所1'); node2.id = 2; node1.add(node2);
以下代码是正确的:
node1 = new xyTree.Node('下关分局'); node1.id = 1; tree1.add(node1); node2 = new xyTree.Node('下关派出所1'); node2.id = 2; node1.add(node2); node222 = new xyTree.Node('玄武分局'); node222.id = 3; tree1.add(node222);
1)必须以深度遍历的方式初始化树的所有节点
2)如想修改单击节点的反应要自己写回调函数,见HTML示例
3)点击根节点图标,会收缩,再点击,展开
4)根节点图片和一般节点的缺省图片都可以换,如果不喜欢那个文件夹的话,在本类中修改全局变量xyTree.TreeConfig即可
5)也可以用img属性替节点指定不同的图片
下面给出了一个最简单的例子:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>xyTree</title>
<link type="text/css" rel="stylesheet" href="xyTree/xtree.css" />
<script src="xyTree/TreeNormal.js"></script>
<script src="xyTree/NodeNormal.js"></script>
<script src="xyTree/DivTreeNormal.js"></script>
<script src="data_example3.js"></script>
<script>
function init(){
document.getElementById('ceshi3').appendChild(Content.div);
Content.init();
}
window.onload = init;
</script>
</head>
<body>
<div id="ceshi3"></div>
</body>
</html>
DivTreeNormal(String name) | 构造方法,返回一个DivTreeNormal对象 | name:根节点名称 | 建立一个普通树对象。 |
DivTreeNormal(String name,String img) | 构造方法,返回一个DivTreeNormal对象 | name:根节点名称 img:用户指定的根节点图标 |
建立一个普通树对象。并指定了根节点图标 |
tree | TreeNormal | (none) | 只读域,获得树的包含所有节点的对象 |
div | HTMLElement | (none) | 只读域,获得树的div对象 |
init() | (none) | (none) | 把树的第1级节点显示出来,只用于初始化时 |
init(Function funa,Function funb) | (none) | funa:单击节点的回调函数,funb:单击根节点的回调函数 | 把树的第1级节点显示出来,只用于初始化时,并指定单击(根)节点的回调函数 |
add(NodeNormal node) | (none) | node:待添加的1级节点 | 给树添加第一级节点 |
defaultClickRootNode() | (none) | (none) | 默认的单击根节点的响应方法 |
defaultClickNode(Node node) | (none) | node:被点击的节点 | 默认的单击节点的响应方法 |
hideTreeBody() | (none) | (none) | 隐藏树身 |
showTreeBody() | (none) | (none) | 显示树身 |
treename | Stirng | (none) | 只读域,获得树的根节点名称 |
maxlevel | int | (none) | 只读域,获得树的最大级别,就是层数 |
root | NodeNormal | (none) | 只读域,获得树的根节点,然后可以获得所有节点 |
divtree | DivTreeNormal | (none) | 只读域,获得树 |
treeArray | Array:NodeNormal | (none) | 只读域,获得树所有节点对应的一个简单的数组 |
关于给节点加属性: 如想要加属性name2, 可以在js数据文件中设置相应的属性,如下 node1 = new xyTree.Node('下关分局'); node1.id = 1; node1.name2 = '分局'; tree1.add(node1); 就可以了,当然,id属性不是必须的. 还有,自己设的属性名不能是parent,tree等下面表中的属性 如果愿意,可以给节点指定不同图标,如下,也是在js数据文件中。 node1 = new xyTree.Node('下关分局'); node1.img = "images/1.gif"; 通常情况下,要指定就全指定,要么就都不指定。
name | Stirng | (none) | 只读域,节点名称,也就是在页面的显示 |
img | Stirng | (none) | 可读写域,节点的图标路径,初始化节点时指定或者不指定 |
parent | NodeNormal | (none) | 只读域,获得节点的父节点,只有根节点的该属性值为null |
previous | NodeNormal | (none) | 只读域,获得节点的前一个节点 |
next | NodeNormal | (none) | 只读域,获得节点的下一个节点 |
child | Array | (none) | 只读域,获得节点的子节点,数组成员类型还是NodeNormal |
level | int | (none) | 只读域,获得节点的级别,根节点为0 |
tree | TreeNormal | (none) | 只读域,获得节点的树对象,如要获得最外层的树则使用node.tree.divtree |
add(NodeNormal node) | (none) | node:待添加的节点 | 给节点添加子节点 |
使用和DivTreeNormal一样,只是方法多了几个。
DivTree(String name) | 构造方法,返回一个xyTree.DivTree对象 | name:根节点名称 | 建立一个复选框树对象。 |
DivTree(String name,String img) | 构造方法,返回一个xyTree.DivTree对象 | name:根节点名称 img:用户指定的根节点图标 |
建立一个复选框树对象。并指定了根节点图标 从以下版本开始:4.1 |
tree | xyTree.Tree | (none) | 只读域,获得树的节点数组对象 |
div | HTMLElement:div | (none) | 只读域,获得树的DOM对象 |
add(xyTree.Node node) | (none) | node:待添加的1级节点 | 给树添加第一级节点 |
addDynamic(xyTree.Node node) | (none) | node:动态添加的一级节点 | 给树动态添加一级节点,页面上立刻显示,背景渐变 从以下版本开始:4.1 |
addDynamic(Array:xyTree.Node arr) | (none) | arr:动态添加的一级节点数组 | 给树动态添加一批一级节点,页面上立刻显示,背景渐变 从以下版本开始:4.1 |
expandNode(xyTree.Node node) | (none) | node:将要显示的节点 | 树显示指定的节点,有默认的背景渐变时间是300 从以下版本开始:4.1 |
expandNode(xyTree.Node node,int ms) | (none) | node:将要显示的节点,ms:渐变的毫秒间隔 | 树显示指定的节点,背景渐变 从以下版本开始:4.1 |
expandCheckedNode(xyTree.Node node) | (none) | node:将要显示的节点 | 树显示指定的节点并选中,背景渐变,有默认的背景渐变时间是300 从以下版本开始:4.1 |
expandCheckedNode(xyTree.Node node,int ms) | (none) | node:将要显示的节点,ms:渐变的毫秒间隔 | 树显示指定的节点并选中,背景渐变 从以下版本开始:4.1 |
findOneNodeByName(String name) | xyTree.Node | name:想找的节点名称 | 根据名称得到一个节点,如果树有重复名称的节点,则只返回先加载到树里的那一个。 从以下版本开始:4.1 |
findOneNodeById(String | int id ) | xyTree.Node | id:想找的节点id,是用户自己定义的 | 根据id寻找一个节点,用户必须给每个节点设id属性,并保证它的唯一性 从以下版本开始:4.1 |
getNodes() | Array:xyTree.Node | (none) | 返回节点数组,不含子节点,较常用 |
getNodesAll() | Array:xyTree.Node | (none) | 返回节点数组,全部 |
getNodesMoji() | Array:xyTree.Node | (none) | 返回节点数组,末级节点,不一定最后一层 |
getNodesDisplay() | Array:xyTree.Node | (none) | 返回节点数组,正在显示的最末级节点。也就是说,看不到的节点即便它被选中了,也不会返回 从以下版本开始:4.11 |
hideTreeBody() | (none) | (none) | 隐藏树身 |
init() | (none) | (none) | 把树的第1级节点显示出来,只用于初始化时。有默认的点击节点的方法, 默认为点击复选框。 通常状况下用户会在网页初始化程序中调用 |
init(Function funa,Function funb) | (none) | funa:单击节点的回调函数,funb:单击根节点的回调函数 | 把树的第1级节点显示出来,只用于初始化时,并指定单击(根)节点的回调函数 通常状况下用户会在网页初始化程序中调用 从以下版本开始:4.1 |
initClearAllCheckBox() | (none) | (none) | 清除节点的选中状态 从以下版本开始:4.1 |
initTreeForm() | (none) | (none) | 树的形状复位 从以下版本开始:4.1 |
initReset() | (none) | (none) | 树的完全复位,等同于最开始加载状态,实际上是连续执行了上面两个方法 从以下版本开始:4.1 |
isSelectAll() | boolean | (none) | 所有节点是否都被选中,是则true |
showTreeBody() | (none) | (none) | 显示树身 |
公共属性和TreeNormal一样,
treename | Stirng | (none) | 只读域,获得树的根节点名称 |
maxlevel | int | (none) | 只读域,获得树的最大级别,就是层数 |
root | xyTree.Node | (none) | 只读域,获得树的根节点,然后可以获得所有节点 |
divtree | xyTree.DivTree | (none) | 只读域,获得树 |
treeArray | Array:xyTree.Node | (none) | 只读域,获得树所有节点对应的一个简单的数组 |
关于给节点加属性:看NodeNormal类的说明
其实与NodeNormal类差别还是不小的,但是公共属性一样。
name | Stirng | (none) | 只读域,节点名称,也就是在页面的显示 |
img | Stirng | (none) | 可读写域,节点的图标路径,初始化节点时指定或者不指定 |
parent | xyTree.Node | (none) | 只读域,获得节点的父节点,只有根节点的该属性值为null |
previous | xyTree.Node | (none) | 只读域,获得节点的前一个节点 |
next | xyTree.Node | (none) | 只读域,获得节点的下一个节点 |
child | Array:xyTree.Node | (none) | 只读域,获得节点的子节点,数组成员类型还是xyTree.Node |
level | int | (none) | 只读域,获得节点的级别,根节点为0 |
tree | xyTree.Tree | (none) | 只读域,获得节点的树对象,如要获得最外层的树则使用node.tree.divtree |
img | String | (none) | 可读写域,用来设置节点的图片url 从以下版本开始:4.1 |
add(xyTree.Node node) | (none) | node:待添加的节点 | 给节点添加子节点 |
addDynamic(xyTree.Node node) | (none) | node:动态添加的节点 | 给节点动态添加子节点 从以下版本开始:4.1 |
addDynamic(Array:xyTree.Node arr) | (none) | arr:动态添加的节点数组 | 给节点批量的动态添加子节点 从以下版本开始:4.1 |
addDynamic(Array:xyTree.Node arr) | (none) | arr:动态添加的节点数组 | 给节点批量的动态添加子节点 从以下版本开始:4.1 |
loadingGif() | (none) | (none) | 使节点的文件夹图标显示为调用的样子 从以下版本开始:4.12 |
loadingGifRenew() | (none) | (none) | 使节点的文件夹图标显示从调用的样子恢复成正常模样 从以下版本开始:4.12 |
slowChange() | (none) | (none) | 节点背景色渐变,默认300毫秒 从以下版本开始:4.1 |
slowChange(int ms) | (none) | ms:渐变的ms间隔 | 节点背景色渐变 从以下版本开始:4.1 |
expand() | (none) | (none) | 把自己显示出来,在DivTree类中有类似方法,有渐变 从以下版本开始:4.1 |
expandChecked() | (none) | (none) | 把自己显示出来并选中,在DivTree类中有类似方法,有渐变 从以下版本开始:4.1 |
getNodeLink() | Array:xyTree.Node | (none) | 返回从根节点到自己的节点链,0是根节点,最后是自己 从以下版本开始:4.1 |
<!-- -->更新说明:
4.12版更新说明:(2007/07/27) (1)修正重要bug:在IE浏览器中,如果设置 IE->工具->Internet选项->常规->设置->每次访问此页时检查, 那么图片会莫名其妙消失,现已更正。 原因: 单击链接元素会有奇怪的特征,图片会消失 解决方案: (1-1)去除html代码和javascript代码中的href属性,不用。 (1-2)不知为何,样式中鼠标移上的样式没有显示。 (1-3)使用万能的javascript,定义如下,样式当然随便: a.onmouseover = function (){this.style.color='blue';} a.onmouseout = function (){this.style.color='black';} (2)添加Node类的方法loadingGif()和loadingGifRenew()方法 会使节点的文件夹图标显示为调用的样子,另一个恢复 (3)写了一个模拟ajax的示例,有些不满意,主要是 其实节点是有子节点的,可是第一次显示出来时是个文件图标而非文件夹图标, 加号也是的,将来可能会写一个AjaxTreeNormal类和AjaxTree类。 难道要使用多重继承吗?不敢想象。 (4)小插曲:火狐中允许非标准数组写法[1,3,77,],而IE中只有标准数组写法[1,3,77] 另:火狐中鼠标的指针样式cursor好像可选值要少一些,IE多一些 (5)这一版更新的文件很多,不再列举 (2)本来说这一版要实现继承的,但未实现。为了不食言,定义为4.11版。 (3)关于IE显示图片丢失的情况,确保IE->工具->Internet选项->常规-> 设置->自动,情况就好多了。这也是IE默认配置。 如果设置为“每次访问此页时检查”(显然是Web程序员的设置)会丢失图片,但在图片处右击鼠标, 选择“显示图片”,倒也能显示,奇怪的IE。 4.11版更新说明:(2007/07/21) (1)添加DivTree树的第4个返回节点的函数getNodesDisplay, 意思是根据当前树的展开形状返回最末级节点,这个最末级节点是眼睛看到的, 不一定是真正的叶节点。 (2)本来说这一版要实现继承的,但未实现。为了不食言,定义为4.11版。 (3)关于IE显示图片丢失的情况,确保IE->工具->Internet选项->常规-> 设置->自动,情况就好多了。这也是IE默认配置。 如果设置为“每次访问此页时检查”(显然是Web程序员的设置)会丢失图片,但在图片处右击鼠标, 选择“显示图片”,倒也能显示,奇怪的IE。 4.1版更新说明:(2007/06/16) (1)使用方法大改变,现在用户只需把xyTree文件夹和html文件放到一起就可以了, 目录结构更加清晰,更像是一个组件包了。 (2)添加了命名空间xyTree,为此修改了所有的js文件和css文件,还包括数据js文件. 所以原先的用户需要替换程序js文件和css文件,还修改数据js文件,是有点麻烦。 (3)原先在html文件中是: document.getElementById('ceshi1').appendChild(treeXiaqu.div); treeXiaqu.init(); //这句话不会象前一版本默认有对话框弹出 现在默认是点击复选框或文件夹(视哪种树而定,提供缺省单击的行为,见示例5和示例6), 如果用户不满意,可以自己写回调函数,见下面的说明(8) (4)去除了一个小bug,如果用户仍然想使用4.0版的树,可以,但必须自己改DivTree.js 第326行原先是 this.div.firstChild.firstChild.src = TreeConfigNormal.rootIcon; 应改成: this.div.firstChild.firstChild.src = TreeConfig.rootIcon; 第331行原先是 this.div.firstChild.firstChild.src = TreeConfigNormal.openRootIcon; 应改成: this.div.firstChild.firstChild.src = TreeConfig.openRootIcon; (5) 现在可以对节点方便的指定图片,如果不指定,就使用 TreeConfig或TreeConfigNormal的缺省图片。 不管哪种树,想指定根节点就在树(在js数据文件中)的构造方法的第二个参数填上图片路径, 想指定节点的图标就在初始化节点时(在js数据文件中)加img属性,见文档中的说明。 还可以改样式表第21行的样式,这个样式决定了指定的图片样式,而不会影响缺省图片的样式。 (6) 添加了一个复选框树的方法,initClearAllCheckBox(), 可以清空树的所有被选中的复选框,树的形状不变。 (7) 添加了一个复选框树的方法,initTreeForm(), 可以把树的节点展开形状恢复到初始状态,但节点的选中情况不变 (8) 添加了一个复选框树的方法,initReset(), 可以清空树的所有被选中的复选框,并且把树的节点展开形状恢复到初始状态。 (9) 添加了我刚刚学会的回调函数的用法, 回调函数的用法是这样的: 程序库中(就是我写的程序) function a(funb){ //执行一些过程,结果保存在result变量中 var result = /* 结果 */; funb(result); //funb是个您写的函数的名称 } 而您写的程序(html或js)中有这个函数 function funbbb(resu){ alert(resu); /*在这里就得到了结果,可能是对象或数值,并可以随便使用*/ } 您这样调程序库 a(funbbb); 上面这句的意思是先到程序库中执行一个函数,然后,自动 返回到您写的函数中,还能从参数中得到结果。参数的个数最好与库的开发者指定的个数相同。 回调函数的好处是:隔离了库和用户,现在您不必修改程序库也可以自由使用(注意作用域)。 当然您要改了再用,也没关系,改吧。 这我这里,回调函数的确是一种“漂亮的解决方案”, 主要是用户的html中树的初始化方法先暂时有两种。 第一种:treeXiaqu.init();//提供默认的行为 第二种:treeXiaqu.init(funa,funb)//见示例和文档 (10)可以动态添加节点了,不能删除,也不打算做,又开始跟刚开始写这个程序时一样鼓捣竖线,加号,文件夹 (11)节点的颜色渐变, (12)还有一些琐碎方法不再列举了 4.0版更新说明:(2007/05/16) 1)在IE6.0和FireFox2.0上测试通过,其实就css文件里多了一句话 2)专门加了一个API使用文档。 3)为了在同一个文件中混合使用两种树,改类名了, 4)添加了隐藏树身和显示树身的方法 3.1版更新说明 (1)图片改成gif (2)对对象的命名有了好方法。 3.0版更新说明: 新增方法: (1)树的方法getNodesAll(),返回一个数组,所有被选中的节点(当然不含半灰色的节点,下同) (2)树的方法getNodesMoji(),返回一个数组,末级所有被选中的节点,注意不一定是最后一层。 (3)把单击一般节点和根节点的方法放到DivTree.js文件的最后,方便使用者修改。 (4)单击一般节点的方法:clickNode() (5)单击根节点的方法:clickRootNode(),一般用户都要修改 (6)又把单击根节点的图标的方式修改了, 改成和最开始一样,点一下,其余节点消失,再点出现。 (7)试图用document.createDocumentFragment()优化代码,不过看起来没什么效果。 2007/02/09 新加方法判断是否根节点被选中 isSelectAll(); true表示被选中 false表示不被选中