最近在做一个项目,是一个b/s架构的,在项目中,用到了树形结构,即如图1所示的结构。
在实现的过程中,因为我们的整个项目是基于Ext js实现的,所以首先考虑的是用Ext js的Tree来实现,但是在后来做的过程中发现,由于IE在处理异步并发方面有点问题,导致显示出来的树形结构要么就是完全显示不出来,要么就是当树有多级的时候只能显示第一级,下面的子节点显示不完全。基于上面的错误,测试了好多种方法,最后的结果还是无功而返!所以就在考虑用别的树形结构去实现,这自然而然的就想到了jquery的zTree。相比ext
js,jquery的特点表现的很明显,至于详细的是那些,本文不做详细说明。具体的下面来详细介绍一下ext tree和jquery下树形结构的实现。
一、Ext js tree
1、Ext js简介
ExtJS
是一个很不错的 Ajax
框架,可以用来开发带有华丽外观的富客户端应用,使得我们的 b/s
应用更加具有活力及生命力。ExtJS
是一个用 javascript
编写,与后台技术无关的前端 ajax
框架。因此,可以把 ExtJS
用在.Net、Java、Php
等各种开发语言开发的应用中。
ExtJs
最开始基于 YUI
技术,由开发人员 Jack Slocum
开发,通过参考 Java Swing
等机制来组织可视化组件,无论从 UI
界面上 CSS
样式的应用,到数据解析上的异常处理,
都可算是一款不可多得的 JavaScript
客户端技术的精品。
2、
获得与引用Ext js
要使用 ExtJS,那么首先要得到 ExtJS库文件,该框架是一个开源的,可以直接从官方
网站下载,网址
http://extjs.com/download。下载下来后,可以看到如图2所示的文件。
说明:
1、adapter:负责将里面提供第三方底层库(包括
Ext 自带的底层库)映射为 Ext
所支持的底层库。
2、build:压缩后的 ext
全部源码(里面分类存放)。
3、docs: API
帮助文档。
4、exmaples:提供使用 ExtJs
技术做出的小实例。
5、resources:Ext UI
资源文件目录,如 CSS、图片文件都存放在这里面。
6、source:无压缩 Ext
全部的源码(里面分类存放)
遵从 Lesser GNU
(LGPL)
开源的协议。
7、Ext-all.js:压缩后的 Ext
全部源码。
8、ext-all-debug.js:无压缩的 Ext
全部的源码(用于调试)。
9、ext-core.js:压缩后的 Ext
的核心组件,包括 sources/core
下的所有类。
10、ext-core-debug.js:无压缩 Ext
的核心组件,包括 sources/core
下的所有类。
应用 extjs
需要在页面中引入 extjs
的样式及 extjs
库文件,样式文件为
resources/css/ext-all.css,extjs
的 js
库文件主要包含两个,adapter/ext/ext-base.js及ext-all.js,其中
ext-base.js表示框架基础库,ext-all.js是 extjs
的核心库。adapter表示适配器,也就是说可以有多种适配器,因此,可以把 adapter/ext/ext-base.js
换成 dapter/jquery/ext-jquery-adapter.js
,或adapter/prototype/ext-prototype-adapter.js
等。因此,要使用 ExtJS
框架的页面中一般包括下面几句:
<link
href="../ext/resources/css/ext-all.css"
rel="stylesheet"
type="text/css" />
<script
src="../ext/adapter/ext/ext-base.js"
type="text/javascript"></script>
<script
src="../ext/ext-all.js"
type="text/javascript"></script>
此外,如果想使用汉语的话还得加入以下代码:
<script
src="../ext/src/locale/ext-lang-zh_CN.js"
type="text/javascript"></script>
在 ExtJS
库文件及页面内容加载完后,ExtJS
会执行 Ext.onReady
中指定的函数,因此一般情况下每一个用户的ExtJS应用都是从 Ext.onReady
开始的,使用 ExtJS应用程序的代码大致如下:
Ext.onReady(function () {
Ext.MessageBox.alert("Message","Hello World!");
})
执行的结果如图3(左)所示。
当加入汉语言包之后的结果如图3(右)所示。
3、简单的Ext js树形结构
树控件由 Ext.tree.TreePanel
类定义,控件的名称为 treepanel,TreePanel
类继承自 Panel面板。在 ExtJS
中使用树控件其实非常简单,我们先来看下面的代码:
<script
type="text/javascript">
Ext.onReady(function () {
var root = new Ext.tree.TreeNode({
id:
"root",
text:
"树的根"
});
root.appendChild(new Ext.tree.TreeNode({
id:
"c1",
text:
"子节点1"
}));
var tree =
new Ext.tree.TreePanel({
renderTo:
"tree",
root: root,
width: 100
});
});
</script>
代码的第一句使用 new Ext.tree.TreeNode
类来创建一个树节点,第二句使用树节点的
root的appendChild方法来往该节点中加入一个子节点,最后直接使用new
Ext.tree.TreePanel
来创建一个树面板,要树面板的初始化参数中指定树的 root
属性值为前面创建的 root
节点,也就是树根节点。接下来在<html></html>标签中引用<div id=”tree”></div>将上面的树形结构显示出来!上面的程序执行效果如下图所示:
4、异步树
Ext JS的树控件提供了对这种功能的支持,你只需要在创建树控件的时候,通过给树指定一个节点加载器,可以用来从服务器端动态加载树的节点信息。我们来看下面的代码:
Ext.onReady(function () {
var Tree = Ext.tree;
var tree = new Ext.tree.TreePanel({
el:
'treepanel',
autoScroll:
true,
rootVisible:
false,
loader:
new Tree.TreeLoader({
dataUrl:
'extTree.ashx'/// <reference path="extTree.ashx" />
}),
root:
new Ext.tree.AsyncTreeNode({})
});
tree.render();
})
extTree.ashx这个 url
返回的内容如下:
[
{"cls":"folder","id":101,"leaf":false,expanded:true,"text":"12336报处理流程","children":[
{"cls":"users","id":10101,"leaf":true,"children":null,"text":"12336电话接听"},
{"cls":"file","id":10102,"leaf":true,"children":null,"text":"审核"},
{"cls":"users","id":10103,"leaf":true,"children":null,"text":"案件登记"},
{"cls":"file","id":10104,"leaf":true,"children":null,"text":"领导签字办理意见"},
{"cls":"file","id":10105,"leaf":true,"children":null,"text":"转盟市办理"},
{"cls":"file","id":10106,"leaf":true,"children":null,"text":"反馈办理情况"},
{"cls":"file","id":10107,"leaf":true,"children":null,"text":"盟市调查"},
{"cls":"file","id":10108,"leaf":true,"children":null,"text":"反馈办理结果"},
{"cls":"file","id":10109,"leaf":true,"children":null,"text":"归档"}
]},
{"cls":"folder","id":102,"leaf":false,expanded:true,"text":"信访处理流程","children":[
{"cls":"users","id":10201,"leaf":true,"children":null,"text":"来访登记"},
{"cls":"users","id":10202,"leaf":true,"children":null,"text":"信访案件登记"},
{"cls":"file","id":10203,"leaf":true,"children":null,"text":"领导签署办理意见"},
{"cls":"file","id":10204,"leaf":true,"children":null,"text":"转盟市办理"},
{"cls":"file","id":10205,"leaf":true,"children":null,"text":"反馈办理结果"},
{"cls":"file","id":10206,"leaf":true,"children":null,"text":"归档"}
]}
]
运行的结构如下图所示。
只是上面的结果在IE中无法显示出来,这里就涉及到了异步并发以及浏览器的处理能力。为了能够在IE中正常的显示,做了如下的改动:
Ext.onReady(function () {
var Tree = Ext.tree;
var tree = new Ext.tree.TreePanel({
el:
'treepanel',
//autoScroll: true,
rootVisible:
false,
root:
new Ext.tree.AsyncTreeNode({})
});
tree.render();
//加载提示
var loading = null;
function showLoading() {
loading =
new Ext.LoadMask(Ext.get(tree.getEl()), { msg:
"请等待" });
loading.show();
}
function hideLoading() {
loading.hide();
}
showLoading();
Ext.Ajax.request({
url:
'extTree.ashx', /// <reference path="extTree.ashx" />
success:
function (request) {
var data = Ext.util.JSON.decode(request.responseText);
tree.getRootNode().appendChild(data);
tree.getRootNode().expandChildNodes(true);
hideLoading();
},
FAILURE:
function () {
hideLoading();
Ext.MessageBox.show({
title:
'版块管理',
msg:
'对不起,数据加载异常!',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR
});
}
});
})
这是异步树的生成,至于extTree.ashx的内容,里面可以根据需要从数据库中提取并组成类似与extTree.ashx
这个url返回的内容的json格式。此外,调用的url可以是任何后台语言返回的json。
二、jquery zTree
1、jquery zTree简介
zTree是利用JQuery的核心代码,实现一套能完成大部分常用功能的Tree插件,它具有以下特点:
1)
兼容 IE、FireFox、Chrome
等浏览器
;
2)
在一个页面内可同时生成多个Tree实例
;
3)
支持 JSON
数据
;
4)
支持一次性静态生成和Ajax异步加载两种方式
;
5)
支持多种事件响应及反馈;
6)
支持Tree的节点移动、编辑、删除;
7)
支持任意更换皮肤/个性化图标(依靠css);
8)
支持极其灵活的 checkbox
或 radio
选择功能;
9)
简单的参数配置实现灵活多变的功能。
2、获取和使用jquery zTree
要使用jquery zTree,首先应从网站上获取jquery zTree库文件。下载地址:http://www.ztree.me/v3/main.php,现在的最高版本是3.5.12,下载zTree
-- jQuery 树插件。下载下来解压后的文件如下图:
要使用jquery zTree,首先应在你的web页面中加入以下代码:
<link
href="css/zTreeStyle.css"
rel="stylesheet"
type="text/css" />
<script
src="js/jquery-1.4.2.js"
type="text/javascript"></script>
<script
src="js/jquery.ztree-2.6.min.js"
type="text/javascript"></script>
zTreeStyle.css为jquery zTree为样式文件库,jquery-1.4.2.js为jquery库,jquery.ztree-2.6.min.js则定义了ztree库。
3、简单的zTree
首先,看看下面的代码。
<SCRIPT type="text/javascript">
<!--
var setting = {
data: {
simpleData: {
enable: true
}
}
};
var zNodes =[
{ id:1, pId:0, name:"父节点1 -
展开", open:true},
{ id:11, pId:1, name:"父节点11 -
折叠"},
{ id:111, pId:11, name:"叶子节点111"},
{ id:112, pId:11, name:"叶子节点112"},
{ id:113, pId:11, name:"叶子节点113"},
{ id:114, pId:11, name:"叶子节点114"},
{ id:12, pId:1, name:"父节点12 -
折叠"},
{ id:121, pId:12, name:"叶子节点121"},
{ id:122, pId:12, name:"叶子节点122"},
{ id:123, pId:12, name:"叶子节点123"},
{ id:124, pId:12, name:"叶子节点124"},
{ id:13, pId:1, name:"父节点13 -
没有子节点", isParent:true},
{ id:2, pId:0, name:"父节点2 -
折叠"},
{ id:21, pId:2, name:"父节点21 -
展开", open:true},
{ id:211, pId:21, name:"叶子节点211"},
{ id:212, pId:21, name:"叶子节点212"},
{ id:213, pId:21, name:"叶子节点213"},
{ id:214, pId:21, name:"叶子节点214"},
{ id:22, pId:2, name:"父节点22 -
折叠"},
{ id:221, pId:22, name:"叶子节点221"},
{ id:222, pId:22, name:"叶子节点222"},
{ id:223, pId:22, name:"叶子节点223"},
{ id:224, pId:22, name:"叶子节点224"},
{ id:23, pId:2, name:"父节点23 -
折叠"},
{ id:231, pId:23, name:"叶子节点231"},
{ id:232, pId:23, name:"叶子节点232"},
{ id:233, pId:23, name:"叶子节点233"},
{ id:234, pId:23, name:"叶子节点234"},
{ id:3, pId:0, name:"父节点3 -
没有子节点", isParent:true}
];
$(document).ready(function(){
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
});
//-->
</SCRIPT>
上面的代码定义了一颗简单的树形结构,在body标记中加入<ul id="treeDemo" class="ztree"></ul>将上面的树显示出来,显示的结果如下:
说明:
1、setting
配置信息说明
1)
普通使用,无必须设置的参数
2)
与显示相关的内容请参考 API
文档中 setting.view
内的配置信息
3)
name、children、title
等属性定义更改请参考 API
文档中 setting.data.key
内的配置信息
2、treeNode
节点数据说明
1)
标准的 JSON
数据需要嵌套表示节点的父子包含关系
例如:
var nodes = [
{name: "父节点1", children: [
{name: "子节点1"},