摘要:对于树型菜单大家已经见得很多了,无论是软件中树菜单的制作还是基于WEB的树型菜单的应用,这个看似很简单的菜单在具体实现和效率方面有很大的差别,对于节点数量小,节点层数小的树型菜单来说我们用各种方法实现的结果基本差不多,但是对于层树很多,节点数量很大,关系复杂的树壮菜单而言各种实现办法之间是相差很大的,本文基于几种常用的实现方法来研究其实现方法和效率的问题。
关键字:树型菜单 效率
前言:对于网页中的树状菜单其实现结构大概可以分为以下几种结构:根节点,分支节点,叶节点,树支,对于内层结构可以分为:静态代码实现方式,异步载入模式,而异步载入模式中又可以分为:总体树载入模式和单节点载入模式,对于异步载入模式主要是出于对数据库的操作。同时对于构造树的算法方面大致最常用的也就是:父子节点编号法,和前缀码编号法,而节点的传输方面又可以分为:服务器端动态生成HTML方式,服务器端静态生成HTML方式,客户端保存HTML方式,可以看到这里实现方法很多,也很复杂,所以本文仅仅研究了几种比较成功的例子,虽然部分代码和程序来源于网络,但我还是具体实现了一种利用APPLET方式生成动态树,并且是单节点刷新的方法,而且能重用,具体实现思想和设计模式将在本文最后的实例分析中可以看到。
正文:
1.理论分析:
1.1语言实现方法分析:各种实现方法之间由于所在的平台不同可能表现出的优越性不同,但是其本质,也就是编译方式和解释方式决定了其效率的高低,下面我们比较几种实现方式的具体差异,从最低层来看看他们本应该存在的差异。
运行原理:作为一种脚本语言,用于实现HTML网页中的动态操作,其运行原理和一般程序不一样,而是在程序运行的过程中被逐行解释的,同时它是以事件驱动的方式完成对事件的处理。
特点及其局限性:跨平台可以说是它最大的特点,给它带来优点的同时也带来了很多局限性,比如:游览器的局限性和安全性有关的局限性,但是因为它和HTML很好的结合模式,从而也导致了它是应用很广的一门脚本语言。
运行原理:属于嵌入到游览器环境中的程序,必须由游览器的虚拟机(JVM)负责执行。当在本地编译完成以后,生成字节码文件,这样我们就可以通过导入字节码文件的方式,来实现我们的操作。
特点及其局限性:和Javascript一样也有垮平台性,但是我们只需要对其编译完以后用户就可以很方便的实现其功能,同时因为是java的一种嵌入式开发模式,我们可以很方便的利用SWING组件和其中的类,这样会给我来很高的效率。
1.2数据加载模式分析:具体各以分为一次性加载数据模式和异步加载模式。
1.3节点信息传输问题:在浏览器里显示的树结构其实都是一个个 HTML 元素组合起来的,在 WEB 页面里的树都是根据树节点的信息组合成一串的 HTML 元素列来显示,这一步从节点信息到 HTML 的转化可以在两个地方生成:一个是在服务器端,一个是在客户端。
1.4树结构实现算法分析:
ID号 |
父节点ID |
1 |
1 |
2 |
1 |
3 |
1 |
4 |
3 |
5 |
1 |
6 |
5 |
搜索成的树型图:(图
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
搜索结果不同:(图
+ 1 + 1
+ 2 + 3
+ 3 + 2
+ 4 + 4
+ 5 + 5
+ 6 + 6
没有互换之前的搜索兔 互换后的搜索图
*说明:我们把节点号为2和3的节点在数据库中互换位置,得到不同的结果,虽然这样一个节点的子节点个数和相关信息没有变化,但是对于自身在父节点中的位置也发生了变化,对于某些需要具体顺序的应用将产生很大影响。
编码例子:
ID |
0 |
0.1 |
0.2 |
|
0.3 |
|
搜索结果:
+ 0
+ 0.1
+ 0.2
+
+ 0.3
+
2.具体实现方法:
由于涉及的语言方面的实现方法很多,本文只对网上比较流行的实现方法HTML结合javascript的方法还有java-applet实现方法进行了分析,同时对于各种软件制作树状菜单的原理也进行了分析。
2.1 HTML-javascript实现方法:我们利用HTML完成对节点信息的描叙,这完全是静态的添加HTML代码的操作,同时用利用javascript脚本来实现对节点的事件处理。
<!DOCTYPE HTML PUBLIC "-//W
<html>
<head>
<title></title>
<link type="text/css" href="css/tree.css" rel="stylesheet">
<script language=javascript>
function ChangeStatus(o)
{
if (o.parentNode)
{
if (o.parentNode.className == "Opened")
{
o.parentNode.className = "Closed";
}
else
{
o.parentNode.className = "Opened";
}
}
}
</script>
</head>
<body>
<div class="TreeMenu" id="CategoryTree">
<h4>CSS树形菜单</h4>
<ul>
<li class="Opened"><img class=s src="css/s.gif" onclick="javascript:ChangeStatus(this);"><a href="#">根节点</a>
<ul>
<li class="Opened"><img class=s src="css/s.gif" onclick="javascript:ChangeStatus(this);"><a href="#">我的文档</a>
<ul>
<li class="Opened"><img class=s src="css/s.gif" onclick="javascript:ChangeStatus(this);"><a href="#">JavaScript</a>
<ul>
<li class="Child"><img class=s src="css/s.gif"><a href="#">1</a></li>
<li class="Child"><img class=s src="css/s.gif"><a href="#">2</a></li>
<li class="Child"><img class=s src="css/s.gif"><a href="#">3</a></li>
<li class="Child"><img class=s src="css/s.gif"><a href="#">4</a></li>
<li class="Child"><img class=s src="css/s.gif"><a href="#">5</a></li>
<li class="Child"><img class=s src="css/s.gif"><a href="#">6</a></li>
<li class="Child"><img class=s src="css/s.gif"><a href="#">生成node</a></li>
</ul></li>
</ul>
</div>
</body>
</html>
<liclass="Opened"><imgclass=ssrc="css/s.gif"onclick="javascript:ChangeStatus(this);"><a href="#">根节点</a> 进行控制,对于每个分支节点我们都需要添加这条,对于各个父节点的子节点的数量我们必须通过添加如下代码实现,<li class="Child"><img class=s src="css/s.gif"><a href="#">1</a></li>,这样我们就可以实现HTML的静态显示,用javascript来实现事件控制,对于图片加载还需要说明的是,我们看到的节点的图片是加载进去的,同时对于连线的效果也是加载进去的,这也是这次研究的一个发现,对于这个代码如何处理事件是利用函数ChangeStatus来控制的。
2.2 HTML-javascript动态加载实现方法:(说明:这个实例是引用网友“meizz”提供的MzTreeView1.0,其控件被CSDN论坛进行修改,而作为其论坛的树状导航菜单)这里的动态加载实现方法事实上就是从数据库中获得相关的节点信息,再构造出树结构。
A.采用数据一次性加载:把获得的树信息一次性加载给用户,减轻了服务器的负担和访问次数。
B.节点信息的压缩传输:节约了在传送节点信息的HTML文件的时候文件过于庞大。
C.数据库设计:采用父子节点编码方法,结构简单,清晰,同时为每个节点添加了对应的脚本操作,这样节省了打开各个节点时的时间。
D.异步展示:对于整个节点的HTML文件的生成不是以整体的方式展示在用户面前,而是以单单要显示的页面而生成其HTML。
E.采用文字树线:这样避免了对于图片树线的加载,使得展开速度更加快。
F.控件的扩展性:控件的扩展性和重用性都比较高。