原创 面向对象的javascript目录树控件设计与应用 收藏

原文出自:http://www.9499.net?go=tc,阿赖原作

关键字:Web控件 目录树菜单 树型菜单?树形目录 Javascript编程

摘要:本文介绍阿赖javascript目录树控件程序的设计与应用。想了解更多请点这里,想下载控件程序和教程请点这里


阿赖目录树控件程序简介

之前我曾经使用ASP设计过生成目录树的程序,那就是Open Host系统的目录树,完成于20031月份,在此之前浏览过www.9499.net的朋友对此一定有印象。如今使用javascript设计的这个目录树控件程序方法上与ASP有很大的差别,可以说难度更大,使用上更具灵活性,它是目前功能最强使用最简便的目录树程序。关于这个目录树控的功能特性方面,以下几点值得一提:

一、引入了图片控件与目录树控件配合使用,大大提高了灵活性。这一点上主要参考了VB6TreeView控件

二、在控件程序中引入了事件处理机制,增强了功能,也大大提高了使用的灵活性。

三、提供了大量的对象接口和方法。

四、提供了多种添加目录树节点的方法,有add方法,addLink方法,以及独创的pathParse方法(用来解析路径列表,以最简单的代码快速的构造目录树)

五、目录树样式不受限制,用户完全可以设计出风格各异,灵活多变的目录树来。

六、提供多种现成的目录树模板,用户不必再费心去设计目录树样式,只需选取喜欢的模板,添加树节点即可,多快好省!

七、控件程序可根据需要进行功能扩展,目前提供checkbox节点扩展程序(alai_tree_check.js)就是一个很好的范例。

I. 概述:

阿赖目录树控件程序完全采用面向对象的方法设计,整个程序封装一个函数alai_tree()里面,另外随目录树程序提供了一个图片列表imagelist控件(alai_imagelist())。使用阿赖目录树控件程序构建目录树一般遵循以下三个步骤:

一、建立imagelist实例对象,并向控件添加建目录树所需的图片;

二、新建一个目录树控件实例,将上述imagelist实例对象作为第一个参数传递;

三、调用目录树控件的各种对象、方法,添加节点,定义事件处理程序等。

当然我们有更便捷的方法,就是使用现有的目录树模板程序以更简化的步骤来构建目录树,关于模板程序搁后再谈。在建立目录树前我先来理解目录树控件的三个核心对象:

(1)目录树控件实例对象(tree),如下:

??? var tree=new alai_tree()

??? 这样就新建了一个树对象。

(2)根(root)对象:tree.root,可以看出它是tree的一个成员,它是没有外观表现的,用于构建目录树第一级的节点,是第一级节点的父对象(parent)。

(3)节点(node)对象,对应于目录树上的一个节点,如下:

 var node=tree.add(...) //添加节点,参数先省略不谈

 上面调用目录添加节点的方法,生成了一个新的节点对象:node

这三个对象各自拥有很多的成员对象(属性、方法和事件),具体请查看《目录树控件对象参考》。接下举个例子,来看看构键目录树的过程:

?

II. 示例程序:

var images=new alai_imagelist() //建立imagelist实例对象

images.path="images/" //图片路径

images.add("file.gif","default") //添加图片,第二个参数是键值(key)

images.add("folder") //添加图片,文件后缀".gif"省了,键值缺省取文件名:"folder"

images.add("html","link")? //添加html.gif,键值为link

var tree1=new alai_tree(images,16,divTree1) //注意参数divTree1是目录树放置的地方,

//网页上有这样的代码:

,生成的目录树就插到这里面了。

var root=tree.root

var n1=root.add("节点一","default","js","alert('节点一')")

//等效代码:var n1=tree1.add(root,"last","节点一","n1","","js","alert('节点一')")

/* 下面代码演示各种添加节点的方法 */

var n2=root.add("节点二","folder")

var n23=n2.add("2-3") //添加n2的子节点

var n22=tree1.add(n23,"prev","2-2","n22") //将节点n22添加到n23之前

var n20=tree1.add(n2,"first","2-0","n20","file",) //由于"first"参数,这个节点作为n2的第一个子节点

var n3=tree1.add(root,"last","节点三","folder")

var n31=n3.addLink("http://www.9499.net") //添加n2的子节点

var n32=tree1.add(n3,"last","www.9499.net","n32","page","url","http://www.9499.net") //添加n2的子节点

var colNode=tree.pathParse("/节点四/4-1;/节点四/4-2;/节点四/4-3;/节点五/")

var n4=root.addLink("http://www.9499.net","欢迎访问9499.NET")

 

III. 添加节点的方法:

在上面的示例中我们总共接触到了五种添加目录树节点的方法,先看它们的语法原型:

1.tree.add(toNode,relation,text,key,ico,exeCategory,exeArg)

2.root.add(text,ico,exeCategory,exeArg)

3.root.addLink(url,text,target,ico)

4.node.add(text,ico,exeCategory,exeArg)

5.node.addLink(url,text,target,ico)

6.tree.pathParse(path,pathSeparator,listSeparator)

方法1的功能最全面,涵盖了方法2-5,但部分参数我们很少用到,所以用的较多的还是方法2-5。root对象的add方法总是添加第一级的节点,节点node对象的add方法用于添加节点的子节点。addLink方法方便我们添加有网址链接的节点。pathParse方法可解释一个路径列表生成对应的树结构。各个参数的说明请看目录树控件对象参考

?

IV. 节点关系:

??? 阿赖目录树控件程序对于树结构有一个明晰的逻辑表述,这一点表现在树节点对象的下面几种关系上:

 node.first -- 节点的第一个子节点,若无子节点则为null

 node.last -- 节点的最后一个子节点,若无子节点则为null

 node.next -- 节点下一个相邻的子节点,若node是该层上最后一个结点则为null

 node.prev -- 节点上一个相邻的子节点,若node是该层上第一个结点则为null

 node.parent -- 节点的父节点

 node.chidren -- 节点的子节点(它是一个的集合数组,第个元素是一个节点对象)

对于根对象root:

root.first是第一级节点的第一个节点,root.last是第一级节点的最后一个节点,root.chidren是第一级节点的集合,第一级节点的parent等于root。

?

V. 节点对象的成员对象:

节点对象node包含了一些成员对象(属性),为了方便说明和理解,截了一张图放大后加上标注。如下:

数字所标示的对象依次为:

1.node.exIcon

2.node.icon

3.node.label

4.node.lineIcon[0]

5.node.body

6.node.container

 

VI. 访问节点对象:

1.从上面的示例中我们已经看到add方法会返回新添加的节点对象,将之赋予一个变量,以后随时可以访问。

2.所有添加的节点保存在tree.nodes集合数组中,如对于第一个添加的节点:

 var n0=tree1.add(root,"last","节点一","node0")

  除了n0指向该节点外,tree.nodes[0]也指向该节点,另外我们还指定了一个键值:"node0",因此tree.nodes["node0"]也指向了该节点,因此n0、tree.nodes[0]和tree.nodes["node0"]引用的都是同一个对象。

3.执行目录树节点遍历的方法:可以从root.first开始根据节点关系可按多种方法进行遍历,在此不作深究。如果不关心树的逻辑结构进行遍历推荐的方法是:

for(var i=1;i<tree.count()-1;i++){tree.nodes[i]}

可能你会想到另一种方法:

for(var i=0;i<tree.nodes.length;i++){tree.nodes[i]}

也是可行的,但要注意如果有节点设了键值的话,该节点会被访问两次!

4.其它获得节点对象的方法:

??? (1)树对象的方法:getNodeByPath、getNodeByTier、getSelectNode、getActiveNode

??? (1)节点对象的方法: getSibling、节点关系(next,first,last,prev,parent,children)

VII. 节点的操作:

1.删除节点:node.remove() 或 tree.removeNode(node)

2.子节点的展开与收缩:

??? 展开:node.expand(true),收缩:node.expand(false),自动:node.expand()

??? 展开一个分枝(展开子节点孙子节点):node.expand(true,true)

??? 展开所有节点:tree.expandAll(true),收缩所有节点:tree.expandAll(false)

??? 展开至第二层:tree.expandToTier(2)

?

IX. imagelist控件与目录树控件的关系:

imagelist用于向目录树控件提供构建目录树的各种图片(图标),在目录树控件中这些图片是如何被使用的呢?在添加节点的方法中ico参数是用于设置节点图标的,如上例中n1节点ico为"default",这就是添加节点时指定的键值,除了用键值我们还可以用索引值,因为"default"是第一个添加的图标其索引值为0,用0来代替"default"也是可以的。可见目录树控件是通过键值(字符串)或索引值(正整数)来引用imagelist控件中的图片的。

我们还注意到有些节点添加时ico参数是缺省的,但是该节点还是有图标显示的,这就是要谈的另一个议题--约定键值。约定键值是指imagelist控件中具有这些键值的元素在目录树控件会有特殊的用途,约定键值有以下几种:

1、default -- 默认图标,在ico参数缺省时节点使用默认图标,图例:

2、expandcollapse -- 用于控制子节点展开和收缩,

  常用图例:

3、expand_topexpand_endcollapse_topcollapse_end,在使用上面第一组图例时提供首尾不同的图片

  图例:

4、leaftwig -- 用于指示树叶节点和末稍节点的图标,图例:

5、lineblank -- 用于画目录树支干连线。图例: (blank是一张空白的图片)

6、link -- 特别用于addLink方法,ico参数缺省时使用,图例:

按照这种约定,如果你要显示控制节点展开/收缩的图片,应该在向imaglist添加expand和collapse键值的图片,同理要显示枝干连线就要添加line和blank键值的图片。如果你提供了default图标且添加节点时没有指定的ico参数,default图标就被派上用场了。这是一种非强制的约定,你甚至可以不向imagelist添加任何图片,这样你构建的就是没有图片的树。正是因为这种约定关系使得阿赖目录树程序拥有超强的灵活性,你可以使用各种的组合,选取各种的图标,构建出各式各样的目录树来!

?

XI. 事件处理:

一、事件处理机制:

树对象的事件有:onclick , ondblclick , onmousemove , onmouseover , onmouseout , onmouseup , onmousedown , onkeypress , onkeydown , onkeyup , oncollapse , onexpand , afteradd , onblur , onfocus , onselect

节点对象的事件有:onclick , ondblclick , onmouseover , onmouseout , onmousemove , onmousedown , onmouseup , onkeypress , onkeydown , onkeyup , oncollapse , onexpand , onfocus , onblur , onselect

树对象的事件用于响应所有节点的相应事件,节点对象是针对个别的节点进行处理。有一个很重要的特点:树对象的事件处理程序的第一个参数都是引发该事件的节点对象,节点对象的事件均没有参数。我们注意到两者的事件名几乎相同(tree.afteradd事件例外),对于onclick事件它是这样执行的:当鼠标点击节点时,将会执行node.onclick的事件处理程序,如果处理程序返回值为true,接着执行tree.onclick事件,反之如果node.onclick的处理程序返回值为false(或没有返回值),则tree.onclcik事件不会被执行。其它事件都是类同于此,这就是事件处理机制,有点类似DOM(文档对象模型)的事件冒泡(bubble)。

添加节点add方法的两个参数:exeCategory和exeArgv是用来设置节点要执行的动作,例如:

n1=tree.root.add("test","","js","alert('hello')")

n2=tree.root.add("9499.net","","url","http://www.9499.net")

则单击n1将弹出"hello",单击n2将打开网址www.9499.net。如果缺省这两个参数默认动作是执行expand方法展开或收缩子节点(如果有的话)。单击节点执行的动作实际上是调用node.execute()方法,面execute()方法执行的动作又取决于exeCategory和exeArgv两个参数。node.execute()和onclick事件的联系是这样的:如果tree.onclick事件处理程序返回值为true,将接着调用node.execute()方法,若返回值为false或无返回值,则node.execute()方法不会被执行,这是事件处理机制的别一个方面。

二、事件处理程序:

事件处理程序一般用来控制节点的行为。

示例:如果我们想让节点有类似超链接的效果,即当鼠标移过时文字变蓝,加下划线,但对于节点n11却不想让它如此,可以用下面的事件处理程序实现:

//鼠标移入时
tree.onmouseover=function(srcNode)
{
???? srcNode.label.style.color="blue"
???? srcNode.label.textDecoration="underline"
???? srcNode.label.cursor="hand"
}

//鼠标移出时
tree.onmouseout=function(srcNode)
{
??? srcNode.label.style.color="black"
??? srcNode.label.textDecoration="none"
}

//对节点11特别处理
n11.onmouseover=n11.onmouseout=function(){return false}

另外点击节点时默认动作是让节点获得焦点选择加亮显示,如果不想让节点被选择可以让tree.onselect事件处理程序返回值为false,就可以屏蔽这个行为,如下:

tree.onselect=function(srcNode){return false}

XII.使用模板程序:

阿赖目录树控件程序具有设计多样化树状菜单的能力,为了更方便广大使用者,我们将一些设计好的菜单封装成模板程序,这样用户就可以顺手拈来,省去样式设计的麻烦。模板程序为我们选好了使用的图片,设计了一些基本的事件处理程序,用户只须写添加节点的代码就行了,可谓快速高效,多快好省!在示例目前提供了如下几种常用的模板程序,(以后会有更多更酷的!):

alai_tree_win2k.js -- win2000 explorer风格模板
alai_tree_winxp.js -- winxp explorer风格模板
alai_tree_help.js -- chm帮助风格模板
alai_tree_pretty.js -- 一个很靓的目录树模板
alai_tree_qq.js -- QQ面板模板
alai_tree_cool.js -- COOL面板模板 (真的很酷)

现在我们以win2k模板为例,说明模板程序的使用:

一、首先加载控件程序和模板程序到网页,代码:

<SCRIPT language=JScript src="alai_tree.js"></sript>

<script src="alai_tree_win2k.js" language="JScript"></sript>

二、调用模板,添加节点:

//实例化目录树模板程序,将返回一个树对象。

var tree2=new alai_tree_win2k(divTree) //divTree是目录树放置的地方,如果缺省目录树会放到网页的最前面。

tree2.root.add("节点一")

tree2.root.add("节点二")

看,用这样的方法建目录树多省事!!其实这些模板程序并不复杂,你可以研究一下这些程序然后DIY出属于自己的模板,做出来别忘了跟我分享你的成果!

XIII. 目录树控件功能扩展:

阿赖目录树控件的功能到目前为止已经相当完美,相信你在网上找不到比这功能更强大的目录树程序了,但是它的功能还是不止于此,我们可以根据需要扩充它的功能。alai_tree_check.js是目前提供的一个扩展程序,加载目录树程序后再加载alai_tree_check,目录树控件就会增加具有添加多选按扭checkbox的节点的功能。加载alai_tree_check后目录树将增加如下成员对象:

tree.addChkNode(toNode,text,ico,exeCategory,exeArg,checked) 方法添加具有checkbox的节点(参数用途可参考tree.add方法)

tree.colChkNode 属性,保存具有checkbox的节点的集合数组

tree.oncheck 和 node.oncheck事件 点击checkbox时触发该事件

node.isCheck 属性,用于判断节点是否有checkbox

node.checkBox 属性,节点的checkbox对象

下面结合另一具模板程序pretty的使用来说明该扩展程序的使用:

一、首先加载控件程序,模板程序和扩展程序到网页(注意:扩展程序的加载一定要置后于控件程序),代码:

<script src="alai_tree.js" language="JScript"></sript>
<script src="alai_tree_pretty.js" language="JScript"></sript>
<script src="alai_tree_check.js" language="JScript"></sript>

二、调用模板,添加节点:


var tree3=new alai_tree_pretty(divTree) //divTree是目录树放置的地方,如果缺省目录树会放到网页的最前面。
tree3.root.add("节点一") //添加普通节点
tree3.addChkNode(tree3.root,"节点二") //添加有checkbox的节点

发表于 @ 2004年08月02日 23:35:00|评论(loading...)

新一篇: 让我感到极度郁闷的javascript问题 | 旧一篇: .NET WMI 编程初试

用户操作
[即时聊天] [发私信] [加为好友]
阿赖.COM
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
阿赖.COM的公告

Google ADS

摄影展台

Utilities

总计数:
当前页:
Google搜索

9499.net
文章分类
收藏
BLOG专栏推荐
_★ 申请加入★
coollzh(RSS)
Dream .Net Blog(RSS)
driftingice的专栏(RSS)
griefforyou的程序人生(RSS)
Min.Dom(RSS)
mmkk's weblog
孟子E章的专栏(RSS)
拼搏之路(RSS)
晒太阳的草
最爱白菜(RSS)
活靶子.Net(RSS)
灵感之源(RSS)
精彩秋季 精彩.net(RSS)
翱翔.Net Blog(RSS)
键者天行(RSS)
阿好空间(RSS)
国欣网络
国欣网络社区
国欣网络首页
广发证券云浮营业部网站
我的数码相册
我的留言簿
阿赖Jscript控件程序及教程
热门文章
1.轻轻松松创建目录树菜单
2.ASP.NET动态生成网页图片
3.经典正则表达式
N-Gage使用技巧及问题解决之道
S60手机PC无线遥控器!
VBScript与正则表达式
在N-Gage上折腾一个Hello World程序
小程序大作为,JS工具脚本
搞笑,安全套广告语大全
新欢乐时光病毒源码分析
跟我玩转CSDN BLOG界面
酷!用VB/VB.NET开发各种智能手机应用
面向对象的jscript目录树程序
网址收藏
ASPCOOL Blog
Code Project
CSDN社区
DotNet博客
MSDN
博客园
博客堂
微软高校信息交流中心
无忧脚本
百度搜索
存档
软件项目交易
Csdn Blog version 3.1a
Copyright © 阿赖.COM