树组建xTree与xLoadTree

本文详细介绍了xTree和xLoadTree这两种基于AJAX的树形菜单组件。xTree适用于生成静态树形结构,而xLoadTree则能根据XML动态生成树。文章深入解析了它们的工作原理、API及实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

xTree:[url]http://webfx.eae.net/dhtml/xtree/index.html[/url] 固定显示的树
xLoadTree:[url]http://webfx.eae.net/dhtml/xloadtree/xloadtree.html[/url]动态加载的树
xtree2:[url]http://webfx.eae.net/dhtml/xtree2b/[/url]测试的版本, 融合了xtree和xloadtreexTree
[size=large][b]xTree[/b][/size]  
xTree是一个基于AJAX实现的树形菜单。它的原理就是每次都只加载当前结点下的所有结点,而对开发人员来说,就是只需要按一定的格式,生成一段XML代码。XTREE可以自己定制每个结点的ICON和链接。XTREE是基于对象的,通过XTREE,你无需再自己生成HTML代码,而只要生成相应的JS 对象就可以了。
  XTREE的API很简单,就是一个抽象类WebFXTreeAbstractNode以及该抽象类的两个子类WebFXTree和WebFXTreeItem。这三个类的属性和构造函数,还有方法详见http://webfx.eae.net/dhtml/xtree/api.html
  每个结点有一个状态叫做OPEN,如果结点为OPEN,则可以EXPAND。对于ITEM结点来说,永远返回FALSE。toggle()就是切换,如果为展开的,就收起;如果为收起的,就展开。XTREE生成的是静态树,它不能从XML中生成树,而是只能生成简单的静态的树,看构造函数的参数就可以知道【text】【action】。
[color=red][b]WebFXTreeAbstractNode[/b][/color]
[b]属性[/b]:
id:唯一标识
text: label
action: 链接
open: 标志位,boolean型,是否打开
icon: 图标
openIcon:打开时的图标
parentNode:父结点的Reference
childNodes: 子结点的Reference的集合
[b]方法[/b]:
indent():缩进
toggle():切换
collapse():收起
expand():展开
collapseAll():收起全部
expandAll():展开全部
expandChildren():展开子结点
callapseChildren():收起子结点
getNextSibling():取得下一个兄弟结点的Reference
getPreviousSibling():取得上一个兄弟结点Reference
toString():生成HTML代码
[color=red][b]WebFXTree[/b][/color]
[b]构造函数[/b]:new WebFXTree([text], [action], [behavior],[icon],[openIcon]);
[b]参数[/b]:text,action,behavior,icon,openIcon
[b]属性[/b]:rendered 标志位,boolean类型,用于标记该树是否已经生成和显示。
   以及WebFXTreeAbstractNode的所有属性。
[b]方法[/b]:getSelected():返回一个Reference,被选中的那个对象的Reference。
setBehavior(sBehavior): classic,explorer
getBehavior()
以及WebFXTreeAbstractNode的所有方法。
[color=red][b]WebFXTreeItem[/b][/color]
[b]构造函数[/b]:new WebFXTreeItem([text],[action],[parent],[icon],[openIcon]);
[b]属性[/b]:WebFXTreeAbstractNode的所有属性。
[b]方法[/b]:getFirst():返回第一个子结点的Reference
getLast():返回嘴后一个子结点的Reference
[size=large][b]xLoadTree[/b][/size][size=large]——API[/size]
  xLoadTree与xTree的区别就在于,xTree只能生成静态树,而xLoadTree可以根据XML生成动态树。
  xLoadTree是由xTree而来的,主要有两个类:WebFXLoadTree和WebFXLoadTreeItem。其中,WebFXLoadTree继承自WebFXTree,WebFXLoadTreeItem继承自WebFXTreeItem。
[color=red][b]WebFXLoadTree[/b][/color]
这个对象类型用来创建实际的树的根节点, 并且可以被用来向树添加从一个 xml 文件中定义的树节点。WebFXLoadTree 继承自 WebFXTree (请阅读 xTree API),因此WebFXTree提供的所有的属性和方法都可用。
[b]构造函数[/b]:new WebFXLoadTree(sText, sXmlSrc, sAction, sBehavior, sIcon, sOpenIcon)
[b]参数[/b]:sText:树的根节点的文本标签
sXmlSrc:当展开时要加载的xml文件的源路径
sAction:可选,根节点关联的操作(uri地址)
sBehavior:可选,树的表现方式,可用的值包括 "classic" 和"explorer", 当值为 "explorer" 时空节点默认的图标和文件夹图标一样
sIcon:可选,节点所使用的图标文件,如果这个节点是个文件夹,这个值将在节点被关闭的时候使用
sOpenIcon:可选,节点打开时使用的图标文件,这个值仅仅对文件夹节点被打开或者展开的时候有效
[b]属性[/b]:src: 描述子树的xml文件的源路径. 注意这个值将在 xml 文件开始载入后变为只读, 所以任何对这个值的修改只在第一个文件载入之前生效
loading: 标志位,只读,boolean类型,xml 文件开始加载但是尚未加载完的时候为 true,表示正在加载XML文件
loaded: 标志位,只读,boolean类型,xml 文件加载完成的时候为 true, 表示XML文件已将加载完毕
errorText: 只读字符串。如果加载因为任何原因失败,这个原因可以在errorText属性中找到,如果没有错误它的值是 “”(空字符串)
[b]方法[/b]:reload():重新从服务器载入 XML 文件, 并重建这个节点的子节点
所有继承自WebFXTree的方法
[color=red][b]WebFXLoadTreeItem[/b][/color]
这个对象类型用来创建可以加入树根节点的树节点,或者可以作为子目录添加到别的树节点。 当一个 WebFXLoadTreeItem 节点被展开的时候,将会加载用于填充子节点的 xml 文件。WebFXLoadTreeItem 继承自 WebFXTreeItem (请查看 xTree API),因此WebFXTreeItem提供的所有的属性和方法都可用
构造函数:new WebFXLoadTreeItem(sText, sXmlSrc, sAction, eParent, sIcon, sOpenIcon)
[b]参数[/b]:sText:树节点的文本标签
sXmlSrc:当展开时要加载的xml文件的源路径
sAction:可选,节点关联的操作(uri地址)
eParent:可选,当前节点要添加进去的父节点,可以为WebFXTreeItem或者WebFXTree
sIcon:可选,节点所使用的图标文件,如果这个节点是个文件夹, 这个值将在节点被关闭的时候使用
sOpenIcon,可选,节点打开时使用的图标文件,这个值仅仅对文件夹节点被打开或者展开的时候有效
[b]属性[/b]:src: 描述子树的xml文件的源路径。注意这个值将在 xml 文件开始载入后变为只读, 所以任何对这个值的修改只在第一个文件载入之前生效
loading:标志位,只读,boolean类型,xml 文件开始加载但是尚未加载完的时候为 true,表示正在加载XML文件
loaded: 标志位,只读,boolean类型,xml 文件加载完成的时候为 true, 表示XML文件已将加载完毕
errorText: 只读字符串. 如果加载因为任何原因失败, 这个原因可以在 errorText 属性中找到. 如果没有错误它的值时 “”(空字符串)
[b]方法[/b]:reload():重新加载XML文件
所有继承自 WebFXTree 的方法
xLoadTree在调用子节点树的时候,和服务器之间传输的是xml
[color=red][b]xml 格式[/b][/color]
xml 文件中唯一有效的元素就是 tree 节点。一个tree节点可以包含零个,一个或者更多tree节点。
[b]属性[/b](您可以为一个 tree 节点提供 5 个有效的属性)
text:必需,树节点的文本标签
xmlSrc:可选,当展开时要加载的xml文件的源路径
action:可选,节点关联的操作(uri地址)
icon:可选,节点所使用的图标文件。如果这个节点是个文件夹,这个值将在节点被关闭的时候使用
openIcon:可选,节点打开时使用的图标文件。这个值仅仅对文件夹节点被打开或者展开的时候有效
[b]DTD[/b]
xml 文件并不必须是有效的格式才能工作(只需要良好的组织起来),但是如果你想确保你没有写错,可以使用下面的文档类型定义
  <!ELEMENT tree (tree*)>
  <!ATTLIST tree
   text CDATA #REQUIRED
   src CDATA #IMPLIED
   action CDATA #IMPLIED
   icon CDATA #IMPLIED
   openIcon CDATA #IMPLIED>
   target CDATA #IMPLIED>

其中text为显示文本,src为下级目录目录的地址,action为点击的链接,icon为图标,openIcon为节点打开后的图标,target为目标,和a标签的target用法一样。
在你的xml文件中使用这个 dtd 请在文件的开头包含一个 DOCTYPE。下面显示的是 tree.dtd.xml。这个表示了和 tree.xml 中相同的 xml 树,只不过有一个 DOCTYPE 声明。
<?xml version="1.0"?>
<!DOCTYPE tree SYSTEM "tree.dtd">
<tree>
<tree text="Loaded Item 1" action="href://webfx.eae.net" />
<tree text="Loaded Item 2">
<tree text="Loaded Item 2.1" action="javascript:alert(2.1)" />
</tree>
<tree text="Load "tree1.xml"" src="tree1.xml" />
</tree>

[size=large][b]xLoadTree[/b][/size][size=large]——实现[/size]
主要的思路就是创建 WebFXTree 和 WebFXTreeItem 的子类,并且重载 expand 方法来启动加载 xml 文件的过程。一旦加载结束,xml 文件被转换成 WebFXTreeItems 和WebFXLoadTreeItems,然后添加到树上。(这里就是面向对象的好处了,我也用重载或者添加新方法的思路实现了动态添加子节点,添加失败则回复到原来状态,成功则加入新的子节点)
[color=red][b]WebFXLoadTree[/b][/color]
首先我们创建了一个新的构造器,在这个方法里面我们首先调用父类的构造器来确保每个实例可以被正确的初始化。在此之后我们设置一些属性值,最后我们检查树是否已经被打开, 如果这样的话我们就开始加载树的子节点。反之,我们向树节点中添加一个临时的显示正在加载文本的树节点。
function WebFXLoadTree(sText, sXmlSrc, sAction, sBehavior, sIcon, sOpenIcon) {
// call super
this.WebFXTree = WebFXTree;
this.WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon);

// setup default property values
this.src = sXmlSrc;
this.loading = false;
this.loaded = false;
this.errorText = "";

// check start state and load if open
if (this.open)
_startLoadXmlTree(this.src, this);
else {
// and create loading item if not
this._loadingItem = new WebFXTreeItem(webFXTreeConfig.loadingText);
this.add(this._loadingItem);
}
}

WebFXLoadTree.prototype = new WebFXTree;

这个构造器是相当的直接,并没有做太多事,尽管如此请注意我们是如何将父类绑定为了一个方法然后调用它的。
现在我们需要重载 expand 方法,但是我们依然需要调用原来的 expand 方法, 因此我们创建了一个新方法_webfxtree_expand来指向WebFXTree的原来的那个 expand 方法对象. 这是个标准的调用父类的方法,但是最初的几次看起来似乎是有点多余。
expand 方法的逻辑是相当的简单. 我们只是检查是否应该开始载入 xml 文件,然后使用父类的expand方法(_webfxtree_expand)来展开它。
// override the expand method to load the xml file
WebFXLoadTree.prototype._webfxtree_expand = WebFXTree.prototype.expand;
WebFXLoadTree.prototype.expand = function() {
if (!this.loaded && !this.loading) {
// load
_startLoadXmlTree(this.src, this);
}
this._webfxtree_expand();
};

[color=red][b]WebFXLoadTreeItem[/b][/color]
这个类和WebFXLoadTree太相似了,对我来说是完全的相同。因为 JavaScript 不提供多重继承,我也不想使用 expandos 来欺骗它,我们只是不得不重复代码。如果您对此感兴趣,这些代码可以在xloadtree.js 中找到。
[color=red][b]载入树[/b][/color]
你可以看到上面已经有了个方法叫 _startLoadXmlTree,它将被用来加载实际的 xml 文件。这个方法使用了严格 XmlHttp 对象来执行真正的加载。对 xml 文件的载入使用了异步方式来防止文件正在读取的时候 UI 被锁定,因此我们等待 onreadystatechange事件被触发之后才继续进行。请阅读 Xml 增强文章 来了解关于 XmlHttp 对象的更多信息。
// creates the xmlhttp object and starts the load of the xml document
function _startLoadXmlTree(sSrc, jsNode) {
jsNode.loading = true;
var xmlHttp = XmlHttp.create();
xmlHttp.open("GET", sSrc, true); // async
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4)
_xmlFileLoaded(xmlHttp.responseXML, jsNode);
};
// call in new thread to allow ui to update
window.setTimeout(function () {
xmlHttp.send(null);
}, 10);
}

一旦 xml 文件加载完毕,我们调用方法 _xmlFileLoaded。这个方法检查我们得到的 xml 文件,如果得到了文件内容我们将递归转换 xml 元素到 js 的 WebFXTreeItem 对象,然后添加他们。一旦 xml 元素转换并添加完毕,我们将删除那个临时的只不过是用来显示正在加载内容的树节点。
// Inserts an xml document as a subtree to the provided node
function _xmlFileLoaded(oXmlDoc, jsParentNode) {
var bIndent = false;
var bAnyChildren = false;
jsParentNode.loaded = true;
jsParentNode.loading = false;

// check that the load of the xml file went well
if( oXmlDoc == null || oXmlDoc.documentElement == null) {
jsParentNode.errorText = parseTemplateString(webFXTreeConfig.loadErrorTextTemplate,
jsParentNode.src);
}
else {
// there is one extra level of tree elements
var root = oXmlDoc.documentElement;

// loop through all tree children
var cs = root.childNodes;
var l = cs.length;
for (var i = 0; i < l; i++) {
if (cs[i].tagName == "tree") {
bAnyChildren = true;
bIndent = true;
jsParentNode.add( _xmlTreeToJsTree(cs[i]), true);
}
}

// if no children we got an error
if (!bAnyChildren)
jsParentNode.errorText = parseTemplateString(webFXTreeConfig.emptyErrorTextTemplate,
jsParentNode.src);
}

// remove dummy
if (jsParentNode._loadingItem != null) {
jsParentNode._loadingItem.remove();
bIndent = true;
}

if (bIndent) {
// indent now that all items are added
jsParentNode.indent();
}

// show error in status bar
if (jsParentNode.errorText != "")
window.status = jsParentNode.errorText;
}

其它一些这个方法中发生更多的事情并不是很重要。有一些代码来检查错误,一些属性被设置,来显示 WebFXLoadTree 和 WebFXLoadTreeItem 的状态。
[color=red][b]转换 Xml[/b][/color]
剩下的唯一要做的重要的事情就是转换 xml 树节点为 js WebFXTreeItem 对象。这在方法_xmlTreeToJsTree 中完成。在这里读取 xml 属性值,如果有 src 属性我们就创建一个WebFXLoadTreeItem 对象,否则就创建 WebFXTreeItem。一旦创建完成,我们就遍历所有 xml 节点的 childNodes,转换并添加他们。
// Converts an xml tree to a js tree. See article about xml tree format
function _xmlTreeToJsTree(oNode) {
// retreive attributes
var text = oNode.getAttribute("text");
var action = oNode.getAttribute("action");
var parent = null;
var icon = oNode.getAttribute("icon");
var openIcon = oNode.getAttribute("openIcon");
var src = oNode.getAttribute("src");

// create jsNode
var jsNode;
if (src != null && src != "")
jsNode = new WebFXLoadTreeItem(text, src, action, parent, icon, openIcon);
else
jsNode = new WebFXTreeItem(text, action, parent, icon, openIcon);

// go through childNOdes
var cs = oNode.childNodes;
var l = cs.length;
for (var i = 0; i < l; i++) {
if (cs[i].tagName == "tree")
jsNode.add( _xmlTreeToJsTree(cs[i]), true );
}

return jsNode;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值