1、dtree.js源码 function Node(id, pid, name, url, title, target, icon, iconOpen, open) { this.id = id; // 节点id this.pid = pid; // 节点父id this.name = name; // 节点显示名称; this.url = url; // 节点超链接地址; this.title = title; // 节点Tips文本; this.target = target; // 节点链接所打开的目标frame(_blank, _parent, _self, _top) this.icon = icon; // 节点默认图标; this.iconOpen = iconOpen; // 节点展开图标; this._io = open || false; // 节点展开标识; this._is = false; // 节点选中标识; this._ls = false; // 同级最后节点标识; this._hc = false; // 包含子节点标识; this._ai = 0; // 节点在节点数组中的索引值,初始值为0 this._p; // 保存父节点对象; }; function dTree(objName,imagePath) { this.config = { target : null, // 默认的节点链接所打开的目标frame(_blank, _parent, _self, _top) folderLinks : true, // true文件夹节点如果有超链地址,点击节点打开超链接而不是展开节点;false忽略超链展开或折叠节点; useSelection : true, // true高亮显示选中的节点;false反之; useCookies : true, // true使用Cookies保存节点状态;false反之; useLines : true, // true使用虚线连接节点的缩进;false反之; useIcons : true, // true使用图标;false反之; useStatusText : false, // false不在状态栏显示节点名称;true反之; closeSameLevel : false, // true同一级节点只能有一个处于展开状态;false反之; inOrder : false, // false在整个节点数组中查找子节点;true在索引大于本节点的数组元素中查找子节点(如果子节点总是在父节点后面添加的话,设为true将加快tree的构建速度); imagePath : null // 图片路径; } this.icon = { root : (imagePath===undefined?'img/base.gif':imagePath + '/img/base.gif'), // 根节点图标 folder : (imagePath===undefined?'img/folder.gif':imagePath + '/img/folder.gif'), // 枝节点文件夹图标 folderOpen : (imagePath===undefined?'img/folderopen.gif':imagePath + '/img/folderopen.gif'), // 枝节点打开状态文件夹图标 node : (imagePath===undefined?'img/page.gif':imagePath + '/img/page.gif'), // 叶节点图标 empty : (imagePath===undefined?'img/empty.gif':imagePath + '/img/empty.gif'), // 空白图标 line : (imagePath===undefined?'img/line.gif':imagePath + '/img/line.gif'), // 竖线图标 join : (imagePath===undefined?'img/join.gif':imagePath + '/img/join.gif'), // 丁字线图标 joinBottom : (imagePath===undefined?'img/joinbottom.gif':imagePath + '/img/joinbottom.gif'), // L线图标 plus : (imagePath===undefined?'img/plus.gif':imagePath + '/img/plus.gif'), // 丁字折叠图标 plusBottom : (imagePath===undefined?'img/plusbottom.gif':imagePath + '/img/plusbottom.gif'), // L折叠图标 minus : (imagePath===undefined?'img/minus.gif':imagePath + '/img/minus.gif'), // 丁字展开图标 minusBottom : (imagePath===undefined?'img/minusbottom.gif':imagePath + '/img/minusbottom.gif'), // L展开图标 nlPlus : (imagePath===undefined?'img/nolines_plus.gif':imagePath + '/img/nolines_plus.gif'), // 无线折叠图标 nlMinus : (imagePath===undefined?'img/nolines_minus.gif':imagePath + '/img/nolines_minus.gif') // 无线展开图标 }; this.obj = objName; // 树对象名称(必须一致) this.aNodes = []; // 节点数组 this.aIndent = []; // 当前节点到根节点次级节点(pid==-1),所有父节点是否是同级节点中的最后一个,如果_ls==true则数组对应元素之为0,反之为1 this.root = new Node(-1); // 默认根节点 this.selectedNode = null; // 选中节点的id(tree初始化之前)或它在字节数组中的索引值_ai(tree初始化之后) this.selectedFound = false; // true存在选中的节点;false反之 this.completed = false; // tree html 文本构造完成 }; dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) { this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open); }; dTree.prototype.openAll = function() { this.oAll(true); }; dTree.prototype.closeAll = function() { this.oAll(false); }; dTree.prototype.toString = function() { var str = '<div class="dtree">\n'; if (document.getElementByIdx) { if (this.config.useCookies) this.selectedNode = this.getSelected(); str += this.addNode(this.root); } else str += 'Browser not supported.'; str += '</div>'; if (!this.selectedFound) this.selectedNode = null; this.completed = true; return str; }; dTree.prototype.addNode = function(pNode) { var str = ''; var n=0; // 默认在整个数组中搜索子节点 if (this.config.inOrder) n = pNode._ai; // 遍历节点数组 for (n; n<this.aNodes.length; n++) { // 只处理直接下级节点 if (this.aNodes[n].pid == pNode.id) { // 临时变量 var cn = this.aNodes[n]; // 设置节点的父节点属性 cn._p = pNode; // 设置节点的数组索引属性 cn._ai = n; // 设置节点包含子节点标识_hc和同级最后节点标识_ls this.setCS(cn); // 设置节点target 属性 if (!cn.target && this.config.target) cn.target = this.config.target; // 判断一个包含子节点的节点在Cookie中是否是展开状态 if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id); // 判断是否允许包含子节点的节点带有超链接地址 if (!this.config.folderLinks && cn._hc) cn.url = null; // 判断节点是否被选中 if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) { // 初始化节点选中标志 cn._is = true; // 从这里开始this.selectedNode值由id变为_ai(节点数组索引) this.selectedNode = n; // 初始化tree的选中标志 this.selectedFound = true; } str += this.node(cn, n); // 判断本级最后一个节点,结束循环 if (cn._ls) break; } } return str; }; dTree.prototype.node = function(node, nodeId) { // 节点前的线条或空白图标 var str = '<div class="dTreeNode">' + this.indent(node, nodeId); if (this.config.useIcons) { // 根据节点类型和状态确定节点的默认图标 if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node); if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node; if (this.root.id == node.pid) { node.icon = this.icon.root; node.iconOpen = this.icon.root; } str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />'; } // 节点文本及动作方法(带超链接、不带超链接) if (node.url) { str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"'; if (node.title) str += ' title="' + node.title + '"'; if (node.target) str += ' target="' + node.target + '"'; if (this.config.useStatusText) str += ' οnmοuseοver="window.status=\'' + node.name + '\';return true;" οnmοuseοut="window.status=\'\';return true;" '; if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc)) str += ' οnclick="javascript: ' + this.obj + '.s(' + nodeId + ');"'; str += '>'; } else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id){ str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">'; } str += node.name; if ((node.url || ((!this.config.folderLinks || !node.url) && node._hc)) && node.pid != this.root.id) str += '</a>'; str += '</div>';