JavaScript实现树形菜单
程序员文章站
2022-03-18 22:09:05
...
随便做了一个例子如下图
[html] 1,用之前需要组织一个这种结构的XML 2,业务类别和功能在数据库中配置一下就好了 比如:"学生管理"配置的在数据库中的状态时001 那么 他的孩子节点 "添加学生信息" 对应数据库配置应该是001的孩子节点, 这个随你怎么配 ,只要能表示是001的孩子节点就可以了、 可以配置为001001,001002,001003后面的三位数代表孩子节点的顺序,前面三位代表。 3,"/student/student.jsp" 功能所对应的JSP也需要在数据库中配置 4,不同的角色有不同的权限,这个自己想配吧。 js代码 [html] function Folder(folderDescription, hreference) //constructor { //constant data this.desc = folderDescription this.hreference = hreference this.id = -1 this.navObj = 0 this.iconImg = 0 this.nodeImg = 0 this.isLastNode = 0 //dynamic data this.isOpen = true this.iconSrc = "ftv2folderopen.gif" this.children = new Array this.nChildren = 0 //methods this.initialize = initializeFolder this.setState = setStateFolder this.addChild = addChild this.createIndex = createEntryIndex this.hide = hideFolder this.display = display this.renderOb = drawFolder this.totalHeight = totalHeight this.subEntries = folderSubEntries this.outputLink = outputFolderLink } function setStateFolder(isOpen) { var subEntries var totalHeight var fIt = 0 var i=0 if (isOpen == this.isOpen) return if (browserVersion == 2) { totalHeight = 0 for (i=0; i < this.nChildren; i++) totalHeight = totalHeight + this.children[i].navObj.clip.height subEntries = this.subEntries() if (this.isOpen) totalHeight = 0 - totalHeight for (fIt = this.id + subEntries + 1; fIt < nEntries; fIt++) indexOfEntries[fIt].navObj.moveBy(0, totalHeight) } this.isOpen = isOpen propagateChangesInState(this) } function propagateChangesInState(folder) { var i=0 if (folder.isOpen) { if (folder.nodeImg) if (folder.isLastNode) folder.nodeImg.src = "ftv2mlastnode.gif" else folder.nodeImg.src = "ftv2mnode.gif" folder.iconImg.src = "ftv2folderopen.gif" for (i=0; i<folder.nChildren; i++) folder.children[i].display() } else { if (folder.nodeImg) if (folder.isLastNode) folder.nodeImg.src = "ftv2plastnode.gif" else folder.nodeImg.src = "ftv2pnode.gif" folder.iconImg.src = "ftv2folderclosed.gif" for (i=0; i<folder.nChildren; i++) folder.children[i].hide() } } function hideFolder() { if (browserVersion == 1) { if (this.navObj.style.display == "none") return this.navObj.style.display = "none" } else { if (this.navObj.visibility == "hiden") return this.navObj.visibility = "hiden" } this.setState(0) } function initializeFolder(level, lastNode, leftSide) { var j=0 var i=0 var numberOfFolders var numberOfDocs var nc nc = this.nChildren this.createIndex() var auxEv = "" if (browserVersion > 0) auxEv = "<a href="http://www.php1.cn/"> else auxEv = "<a>" if (level>0) if (lastNode) //the last 'brother' in the children array { this.renderOb(leftSide + auxEv + "<img name='nodeIcon" + this.id + "' src='ftv2mlastnode.gif' width=16 height=22 border=0></a>") leftSide = leftSide + "<img src='ftv2blank.gif' width=16 height=22>" this.isLastNode = 1 } else { this.renderOb(leftSide + auxEv + "<img name='nodeIcon" + this.id + "' src='ftv2mnode.gif' width=16 height=22 border=0></a>") leftSide = leftSide + "<img src='ftv2vertline.gif' width=16 height=22>" this.isLastNode = 0 } else this.renderOb("") if (nc > 0) { level = level + 1 for (i=0 ; i < this.nChildren; i++) { if (i == this.nChildren-1) this.children[i].initialize(level, 1, leftSide) else this.children[i].initialize(level, 0, leftSide) } } } function drawFolder(leftSide) { if (browserVersion == 2) { if (!doc.yPos) doc.yPos=8 doc.write("<layer id='folder" + this.id + "' top=" + doc.yPos + " visibility=hiden>") } doc.write("<table ") if (browserVersion == 1) doc.write(" id='folder" + this.id + "' style='position:block;' ") doc.write(" border=0 cellspacing=0 cellpadding=0>") doc.write("<tr><td>") doc.write(leftSide) this.outputLink() doc.write("<img name='folderIcon" + this.id + "' ") doc.write("src='" + this.iconSrc+"' border=0></a>") doc.write("</td><td valign=middle nowrap>") if (USETEXTLINKS) { this.outputLink() doc.write(this.desc + "</a>") } else doc.write(this.desc) doc.write("</td>") doc.write("</table>") if (browserVersion == 2) { doc.write("</layer>") } if (browserVersion == 1) { this.navObj = doc.all["folder"+this.id] this.iconImg = doc.all["folderIcon"+this.id] this.nodeImg = doc.all["nodeIcon"+this.id] } else if (browserVersion == 2) { this.navObj = doc.layers["folder"+this.id] this.iconImg = this.navObj.document.images["folderIcon"+this.id] this.nodeImg = this.navObj.document.images["nodeIcon"+this.id] doc.yPos=doc.yPos+this.navObj.clip.height } } function outputFolderLink() { if (this.hreference) { doc.write("<a href="http://www.php1.cn/"> if (browserVersion > 0) doc.write("onClick='javascript:clickOnFolder("+this.id+")'") doc.write(">") } else doc.write("<a>") // doc.write("<a href="http://www.php1.cn/"> } function addChild(childNode) { this.children[this.nChildren] = childNode this.nChildren++ return childNode } function folderSubEntries() { var i = 0 var se = this.nChildren for (i=0; i < this.nChildren; i++){ if (this.children[i].children) //is a folder se = se + this.children[i].subEntries() } return se } // Definition of class Item (a document or link inside a Folder) // ************************************************************* function Item(itemDescription, itemLink) // Constructor { // constant data this.desc = itemDescription this.link = itemLink this.id = -1 //initialized in initalize() this.navObj = 0 //initialized in render() this.iconImg = 0 //initialized in render() this.iconSrc = "ftv2doc.gif" // methods this.initialize = initializeItem this.createIndex = createEntryIndex this.hide = hideItem this.display = display this.renderOb = drawItem this.totalHeight = totalHeight } function hideItem() { if (browserVersion == 1) { if (this.navObj.style.display == "none") return this.navObj.style.display = "none" } else { if (this.navObj.visibility == "hiden") return this.navObj.visibility = "hiden" } } function initializeItem(level, lastNode, leftSide) { this.createIndex() if (level>0) if (lastNode) //the last 'brother' in the children array { this.renderOb(leftSide + "<img src='ftv2lastnode.gif' width=16 height=22>") leftSide = leftSide + "<img src='ftv2blank.gif' width=16 height=22>" } else { this.renderOb(leftSide + "<img src='ftv2node.gif' width=16 height=22>") leftSide = leftSide + "<img src='ftv2vertline.gif' width=16 height=22>" } else this.renderOb("") } function drawItem(leftSide) { if (browserVersion == 2) doc.write("<layer id='item" + this.id + "' top=" + doc.yPos + " visibility=hiden>") doc.write("<table ") if (browserVersion == 1) doc.write(" id='item" + this.id + "' style='position:block;' ") doc.write(" border=0 cellspacing=0 cellpadding=0>") doc.write("<tr><td>") doc.write(leftSide) doc.write("<a href="http://www.php1.cn/"> doc.write("<img id='itemIcon"+this.id+"' ") doc.write("src='"+this.iconSrc+"' border=0>") doc.write("</a>") doc.write("</td><td valign=middle nowrap>") if (USETEXTLINKS) doc.write("<a href="http://www.php1.cn/"> else doc.write(this.desc) doc.write("</table>") if (browserVersion == 2) doc.write("</layer>") if (browserVersion == 1) { this.navObj = doc.all["item"+this.id] this.iconImg = doc.all["itemIcon"+this.id] } else if (browserVersion == 2) { this.navObj = doc.layers["item"+this.id] this.iconImg = this.navObj.document.images["itemIcon"+this.id] doc.yPos=doc.yPos+this.navObj.clip.height } } // Methods common to both objects (pseudo-inheritance) // ******************************************************** function display() { if (browserVersion == 1) this.navObj.style.display = "block" else this.navObj.visibility = "show" } function createEntryIndex() { this.id = nEntries indexOfEntries[nEntries] = this nEntries++ } // total height of subEntries open function totalHeight() //used with browserVersion == 2 { var h = this.navObj.clip.height var i = 0 if (this.isOpen) //is a folder and _is_ open for (i=0 ; i < this.nChildren; i++) h = h + this.children[i].totalHeight() return h } // Events // ********************************************************* function clickOnFolder(folderId) { var clicked = indexOfEntries[folderId] if (!clicked.isOpen) clickOnNode(folderId) return if (clicked.isSelected) return } function clickOnNode(folderId) { var clickedFolder = 0 var state = 0 clickedFolder = indexOfEntries[folderId] state = clickedFolder.isOpen clickedFolder.setState(!state) //open<->close } function initializeDocument() { if (doc.all) browserVersion = 1 //IE4 else if (doc.layers) browserVersion = 2 //NS4 else browserVersion = 0 //other foldersTree.initialize(0, 1, "") foldersTree.display() if (browserVersion > 0) { doc.write("<layer top="+indexOfEntries[nEntries-1].navObj.top+"> </layer>") // close the whole tree clickOnNode(0) // open the root folder clickOnNode(0) } } // Auxiliary Functions for Folder-Treee backward compatibility // ********************************************************* function gFld(description, hreference) { description="<font style=font-size:9pt; font-color: #00ff00;background-color:#ccff99>" + description folder = new Folder(description, hreference) return folder } function gLnk(target, description, linkData) { description="<font style=font-size:9pt; font-color: #0000ff;background-color:#ccff99>" + description fullLink = "" if (target==0) { fullLink = "'"+linkData+"' target=main" } else { if (target==1) fullLink = "'http://"+linkData+"' target=_top" else fullLink = "'http://"+linkData+"' target=main" } linkItem = new Item(description, fullLink) return linkItem } function insFld(parentFolder, childFolder) { return parentFolder.addChild(childFolder) } function insDoc(parentFolder, document) { parentFolder.addChild(document) } // Global variables // **************** USETEXTLINKS = 1 indexOfEntries = new Array nEntries = 0 doc = document browserVersion = 0 selectedFolder=0 jsp代码 [html] <%@ page language="java" import="java.util.*" pageEncoding="gbk"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="http://www.php1.cn/"> <title>My JSP 'tree.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <style type="text/css"> .navtree { background-color: #FFFFFF ; font-family: Arial, Helvetica, sans-serif; border-right: 1px solid black; margin-top: 5px; scrollbar-face-color:#CCCCCC; scrollbar-shadow-color:#FFFFFF; scrollbar-highlight-color:#FFFFFF; scrollbar-3dlight-color:#6B7A92; scrollbar-darkshadow-color:#6B7A92; scrollbar-track-color:#E2E2E2; scrollbar-arrow-color:#6B7A92 } </style> <script type="text/javascript" src="tree.js"></script> <script type="text/javascript" > function parseXml2Tree(str_xml) { var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.loadXML(str_xml); node=xmlDoc.documentElement;//根节点 var i=0;//用来记数父节点数 var h=0;//用来查找父节点 var fp_array=new Array();//用来存放父目录 foldersTree =gFld(node.nodeName);//根目录 fp=foldersTree; //父目录 var f1; //子目录 fp_array[i]=fp; //第一个父目录为根目录 var rootname=node.nodeName; //根节点的名字 getAllNode(node); //执行递归查找节点,生成目录树 initializeDocument(); function getAllNode(currNode) //首先查找根节点,先找其第一个孩子,如果第一个孩子存在及其兄弟,插入目录树,并记录父目录, //然后把第一个节点看作当前根节点,继续查找其第一个孩子。 { //第一个孩子 childNode=currNode.firstChild; if(childNode!=null ) { if(childNode.firstChild!=null) { f1=gFld(childNode.getAttribute("name"),childNode.getAttribute("link")); insFld(fp,f1); fp=f1; fp_array[++i]=fp; h++; }else{ item1= new Item("<font style=font-size:9pt; font-color: #0000ff;background-color:#ccff99>"+childNode.getAttribute("name"),childNode.getAttribute("link")); insDoc(fp,item1); } //递归查找孩子 getAllNode(childNode); } else //如果没有孩子,即叶子 //叶子的兄弟 if(currNode.nodeName==rootname) //如果为根节点返回。 { return; } nextBrother=currNode.nextSibling; if(nextBrother==null ) { currNode=currNode.parentNode; if(currNode.nodeName==rootname) { return; } fp=fp_array[--h]; } else { currNode=nextBrother; if(currNode.firstChild!=null) { f1=gFld(currNode.getAttribute("name"),currNode.getAttribute("link")); insFld(fp,f1); fp=f1; fp_array[++i]=fp; h++; } else { item1= new Item("<font style=font-size:9pt; font-color: #0000ff;background-color:#ccff99>"+currNode.getAttribute("name"),currNode.getAttribute("link")); insDoc(fp,item1); } getAllNode(currNode); } } } </script> </head> <body class="navtree"> <% String str_dom = "<?xml version=\"1.0\" encoding=\"GB2312\"?>"+ "<功能列表>"+ "<业务类别 link=\"\" name=\"学生管理\">"+ "<功能 link=\"/student/student.jsp\" name=\"添加学生信息\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"更改学生信息\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"查看学生信息\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"删除学生信息\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"下载学生列表\"/>"+ "</业务类别>"+ "<业务类别 link=\"\" name=\"成绩管理\">"+ "<功能 link=\"/student/student.jsp\" name=\"成绩查询\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"成绩排名\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"成绩汇总\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"打印成绩\"/>"+ "</业务类别>"+ "<业务类别 link=\"\" name=\"缴费管理\">"+ "<功能 link=\"/student/student.jsp\" name=\"已经交费\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"缴费查询\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"缴费汇总\"/>"+ "</业务类别>"+ "<业务类别 link=\"\" name=\"选课管理\">"+ "<功能 link=\"/student/student.jsp\" name=\"语文\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"数学\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"英语\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"物理\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"化学\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"生物\"/>"+ "</业务类别>"+ "<业务类别 link=\"\" name=\"系统设置\">"+ "<功能 link=\"/student/student.jsp\" name=\"修改密码\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"用户注册\"/>"+ "<功能 link=\"/student/student.jsp\" name=\"用户注销\"/>"+ "</业务类别>"+ "</功能列表>"; str_dom=str_dom.replace('"','\''); int begin_index=str_dom.indexOf("<"); str_dom=str_dom.substring(begin_index+1); begin_index=str_dom.indexOf("<"); str_dom=str_dom.substring(begin_index); %> <script type="text/javascript"> parseXml2Tree("<%=str_dom%>"); </script> </body> </html>