目录树控件简介

目录树控件简介

I. 概述:

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

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

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

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

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

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

    var tree=new tree()

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

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

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

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

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

这三个对象各自拥有很多的成员对象(属性、方法和事件)。

II. 示例程序:

  var images=new aimagelist() //建立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是目录树放置的地方,

//网页上有这样的代码:<div id="divTree1"></div>,生成的目录树就插到这里面了。

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.163.com") //添加n2的子节点

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

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

var n4=root.addLink(www.163.com,"欢迎访问163.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-5root对象的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"]也指向了该节点,因此n0tree.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)树对象的方法:getNodeByPathgetNodeByTiergetSelectNodegetActiveNode

    (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控件中具有这些键值的元素在目录树控件会有特殊的用途,约定键值有以下几种:

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

2expand collapse -- 用于控制子节点展开和收缩,

        常用图例:

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

        图例:

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

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

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

按照这种约定,如果你要显示控制节点展开/收缩的图片,应该在向imaglist添加expandcollapse键值的图片,同理要显示枝干连线就要添加lineblank键值的图片。如果你提供了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方法的两个参数:exeCategoryexeArgv是用来设置节点要执行的动作,例如:

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()方法执行的动作又取决于exeCategoryexeArgv两个参数。node.execute()onclick事件的联系是这样的:如果tree.onclick事件处理程序返回值为true,将接着调用node.execute()方法,若返回值为false或无返回值,则node.execute()方法不会被执行,这是事件处理机制的别一个方面。

二、事件处理程序:

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

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

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

//鼠标移出时
tree.οnmοuseοut=function(srcNode)
{
    srcNode.label.style.color="black"
    srcNode.label.textDecoration="none"
}

//对节点11特别处理
n11.οnmοuseοver=n11.οnmοuseοut=function(){return false}

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

tree.οnselect=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 src="alai_tree.js" language="JScript"></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的节点

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值