经过几天的努力终于完成一个动态读取json数据的简单目录树js控件了,分享一下基础代码(最后更新2008-05-23):
---------------
Tree.js
---------------
function $(id)
{
return document.getElementById(id);
}
var rootid = "";//根节点的全局变量
/*
*
* 解析树
*
*/
function parseTree(responseText)
{
var data = eval('(' + responseText + ')');
//var data = responseText;
var texttmp = data[0].text;
var urltmp = data[0].url;
rootid = data[0].id;
addTreeRoot(texttmp,urltmp,rootid);
parseTreeNode(data[0]);
}
var Nodedepth = 1;//节点深度的全局变量
/*
*
* 解析节点
*
*/
function parseTreeNode(dataObject)
{
var subDataObjects = dataObject.children;
for (var i = 0; subDataObjects != null && i < subDataObjects.length; i++)
{
var subDataObject = subDataObjects[i];
var texttmp = subDataObject.text;
var idtmp = subDataObject.id;
var urltmp = subDataObject.url;
var parentidtmp = dataObject.id;
var lastNode = false;
if(parentidtmp==rootid)
{
Nodedepth = 1;//如果父节点为根节点则把Nodedepth设为1
}
if(typeof(subDataObject.children)!="undefined")
{
addTreeNode(texttmp,urltmp,idtmp,Nodedepth,parentidtmp,lastNode);
Nodedepth = Nodedepth + 1;//如果有子节点则Nodedepth加1
}
else
{
lastNode = true;
addTreeNode(texttmp,urltmp,idtmp,Nodedepth,parentidtmp,lastNode);
if(!subDataObjects[i+1])
{
Nodedepth = Nodedepth - 1;//如果没有子节点和同级后面的节点则Nodedepth减1
}
}
parseTreeNode(subDataObject);//递归函数,这里是核心代码
}
}
var tmpDiv = null;//创建新的div对象的全局变量
/*
*
* 添加根节点
*
*/
function addTreeRoot(texttmp,urltmp,idtmp)
{
tmpDiv = document.createElement("div");
tmpDiv.className = "div0";
tmpDiv.innerHTML= "<a href='"+urltmp+"' target='_self' οnclick='controlNode(\""+idtmp+"\")'>"+texttmp+"</a>";
tmpDiv.id = idtmp;
container.appendChild(tmpDiv);
}
/*
*
* 添加子节点
*
*/
function addTreeNode(texttmp,urltmp,idtmp,Nodedepth,parentidtmp,lastNode)
{
var treeRoot = document.getElementById(parentidtmp);
tmpDiv = document.createElement("div");
tmpDiv.id = idtmp;
if(parentidtmp==rootid)
{
tmpDiv.className = "div"+Nodedepth;
if(document.all)
{
tmpDiv.style.display = "";
}
else
{
tmpDiv.style.display = "table";
}
tmpDiv.innerHTML= "<a href='"+urltmp+"' target='_self' οnclick='controlNode(\""+idtmp+"\")'>"+texttmp+"</a>";
}
else if(!lastNode)
{
tmpDiv.className = "div3 div"+Nodedepth;
tmpDiv.style.display = "none";
tmpDiv.innerHTML= "<a href='"+urltmp+"' target='_self' οnclick='controlNode(\""+idtmp+"\")'>"+texttmp+"</a>";
}
else
{
tmpDiv.className = "div3 div"+Nodedepth;
tmpDiv.style.display = "none";
tmpDiv.innerHTML= "<a href='"+urltmp+"' target='_blank'>"+texttmp+"</a>";
}
treeRoot.appendChild(tmpDiv);
}
/*
*
* 控制节点的打开关闭
*
*/
function controlNode(idtmp)
{
var NodeParent = document.getElementById(idtmp);
var tag = NodeParent.getElementsByTagName("div");
var len = tag.length;
if(tag[0].style.display == ""||tag[0].style.display == "table")
{
closeNode(tag,len);
}
else
{
expandNode(tag,len);
}
}
/*
* 关闭子节点
*/
function closeNode(tag,len)
{
for(var i = 0; i < len; i++)
{
var NodeID = document.getElementById(tag[i].id);
var NodeTag = NodeID.getElementsByTagName("div");
var NodeLen = NodeTag.length;
if(NodeLen!=0)
{
tag[i].style.display = "none";
i = i + NodeLen;
}
else
{
tag[i].style.display = "none";
}
}
}
/*
* 打开子节点
*/
function expandNode(tag,len)
{
for(var i = 0; i < len; i++)
{
var NodeID = document.getElementById(tag[i].id);
var NodeTag = NodeID.getElementsByTagName("div");
var NodeLen = NodeTag.length;
if(NodeLen!=0)
{
for(var j = 0; j < NodeLen; j++)
{
NodeTag[j].style.display = "none";
}
//if(getOs()=="MSIE")
if(document.all)
{
tag[i].style.display = "";
}
else
{
tag[i].style.display = "table";
}
i = i + NodeLen;
}
else
{
//if(getOs()=="MSIE")
if(document.all)
{
tag[i].style.display = "";
}
else
{
tag[i].style.display = "table";
}
}
}
}
/*
*
* 判断浏览器类型
*
*/
function getOS()
{
if(navigator.userAgent.indexOf("MSIE")>0)
{
return "MSIE";
}
else if(isFirefox = navigator.userAgent.indexOf("Firefox")>0)
{
return "Firefox";
}
else if(isSafari = navigator.userAgent.indexOf("Safari")>0)
{
return "Safari";
}
else if(isCamino = navigator.userAgent.indexOf("Camino")>0)
{
return "Camino";
}
else if(isMozilla = navigator.userAgent.indexOf("Gecko/")>0)
{
return "Gecko";
}
else
{
return "";
}
}
----------------
tree.html
----------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title>tree</title>
<style type="text/css">
<!--
a,area { blr:expression(this.onFocus=this.blur()) } /* for IE */
:focus { outline: none; } /* for Firefox */
a:link
{
color:#ff3031; TEXT-DECORATION: none;
}
a:visited
{
color: #ff3031; TEXT-DECORATION: none;
}
a:hover
{
color:green; TEXT-DECORATION:underline;
}
a:active
{
color:green; TEXT-DECORATION: none;
}
#container
{
position: absolute; left: 145px; top: 30px; width: 200px;height:400px;
overflow-y:auto;overflow-x:auto;vertical-align:middle;
background:#000000;color: #ff3031;font-family: "宋体";font-size:12px;
}
.divline
{
padding-left:12px;padding-top:4px;padding-bottom:4px;
text-align:left;
}
#root
{
padding-left:12px;padding-top:4px;padding-bottom:4px;
text-align:left;
}
.div0
{
width:80px;padding-left:12px;
white-space:nowrap;
}
.div1
{
width:80px;padding-left:12px;
white-space:nowrap;
}
.div2
{
width:80px;padding-left:12px;
height:15px;white-space:nowrap;
/*display:none;*/
}
.div3
{
width:80px;padding-left:12px;
height:15px;white-space:nowrap;
}
.false
{
color: #FF0000;
}
.success
{
color: green;
}
-->
</style>
<script type="text/javascript" src="Ajax.js"></script>
<script type="text/javascript" src="Tree.js"></script>
</head>
<body>
<div id="container"> </div>
<script type="text/javascript">
var TimeoutHandler = null;
var container = document.getElementById("container");
function init()
{
clearTimeout(TimeoutHandler);
try
{
Ajax.sendGetRequest("TreeData.jsp",true,"callbackAjax(ME)");
}catch(e)
{
alert(e);
}
//TimeoutHandler = setTimeout ("init()", 2000);
}
function callbackAjax(ajaxHandler)
{
parseTree(ajaxHandler.http_request.responseText);
try
{
ajaxHandler.http_request_handler.http_request.abort ();
ajaxHandler.http_request_handler.flag = 0;
}
catch (e) {}
}
//调用初始化方法
init();
</script>
</body>
</html>
----------------
TreeData.jsp
----------------
<%@ page contentType="text/html; charset=gbk" language="java" errorPage="" %>
<%@ page language="java" import="java.io.PrintWriter"%>
<%
response.setHeader("Cache-Control", "no-cache");
response.setCharacterEncoding("gbk");
PrintWriter xmlout = response.getWriter();
int start = 0;
int limit = 10;
int limit2 = 10;
int limit3 = 10;
int depth1 = 5;
//int limit = (int) (Math.random() * 10*10);
//System.out.println(limit);
String url = "http://www.baidu.com";
//String target = "_blank";
StringBuffer sb = new StringBuffer();
sb.append("[{'text':'根节点','id':'root','url':'javascript:void(0)','depth':'0',");
sb.append("'children':[{'text':'招商研究','id':'study','url':'javascript:void(0)','depth':'1',");
sb.append("'children':[");
for (int i=start;i<limit;i++)
{
sb.append("{'text':'");
if(Math.floor(Math.random() * 100)>50)
{
sb.append("个股研究");
}
else
{
sb.append("大盘研究");
}
sb.append("','id':'");
sb.append("studyNode");
sb.append(i);
sb.append("','url':'javascript:void(0)");
//sb.append(url);
sb.append("','depth':'2");
sb.append("','children':[{'text':'招商研究3','id':'ddd");
sb.append(i);
sb.append("','url':'javascript:void(0)','depth':'3'}]");
sb.append("}");
if(i!=limit-1){
sb.append(",");
}
else
{
sb.append("]},");
}
}
for (int j = 0; j < depth1; j++)
{
sb.append("{'text':'市场信息");
sb.append(j);
sb.append("','id':'info");
sb.append(j);
sb.append("','url':'javascript:void(0)','depth':'1',");
sb.append("'children':[");
for (int i = start;i < limit2; i++)
{
sb.append("{'text':'");
if(Math.floor(Math.random() * 100)>50)
{
sb.append("利好信息");
}
else
{
sb.append("熊市信息");
}
sb.append("','id':'");
sb.append("infoNode");
sb.append(j);
sb.append(i);
sb.append("','url':'");
sb.append(url);
sb.append("','depth':'2");
sb.append("'}");
if(i!=limit2-1){
sb.append(",");
}
else
{
//sb.append("]},");
}
}
sb.append("]},");
}
sb.append("{'text':'客户杂志','id':'magazine','url':'javascript:void(0)','depth':'1',");
sb.append("'children':[");
for (int i = start; i < limit3; i++)
{
sb.append("{'text':'");
if(Math.floor(Math.random() * 100)>50)
{
sb.append("最新杂志");
}
else
{
sb.append("推荐文章");
}
sb.append("','id':'");
sb.append("magazineNode");
sb.append(i);
sb.append("','url':'");
sb.append(url);
sb.append("','depth':'2");
sb.append("'}");
if(i!=limit3-1){
sb.append(",");
}
else
{
sb.append("]}]");
}
}
sb.append("}]");
String rs = sb.toString();
System.out.println(rs);
try
{
xmlout.write(rs);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
xmlout.flush();
xmlout.close();
}
%>