记得才开始接触计算机的时候觉得网络很神奇,输入一个地址就会出来很多很多的东西,后来上大学了,又渐渐的迷上了各种网页特效,觉得这些东西很酷很炫。不过遗憾的是并未认真的研究这些东西,一方面是学校没这方面的课程,更关键的是自己不努力。不过正是由于对这些前台东西的兴趣慢慢的、偶然的带我走进了asp.net的世界。虽然工作和学习中仍旧会和js打交道,但是总是停留在一个很尴尬的阶段,也就只能望复杂js应用而兴叹了。
就拿树来说吧,这应该是一个比较有用的东西了。平时也遇到过一些,但是都交给别人做了,自己一直想仔细研究下也不了了之。这次项目又遇到这样一个应用,这次说什么也要仔细研究下了,经过一天的多的努力(汗啊),终于小有成效:

























目前只是做好了展示节点的逻辑,代码页还有待调整,更完整的树就留在‘下个版本’了。大家不要扔我,因为我一直觉得树节点前面的线线挺难搞的,今天居然搞定了,甚是兴奋,因此先发个样子上来。
批评,我已经准备好了。
附代码:
<!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>
<title>Untitled Page</title>
<style type="text/css">
body
{
font-size:12px;
font-family:微软雅黑;
}
</style>
<script type="text/javascript" src="jquery-1.3.2-vsdoc2.js"></script>
<script type="text/javascript">
var Tree =
{
Resources :
{
Images :
{
TrunkNode :
{
Expanded : "images/folder-open.gif",
Collapsed: "images/folder.gif"
},
LeafNode : "images/leaf.gif",
Lines :
{
Elbow : "images/elbow.gif",
ElbowEnd : "images/elbow-end.gif",
ElbowLine :"images/elbow-line.gif",
Blank : "images/blank.gif"
}
}
},
Styles :
{
NodeHeight : "16px"
},
///<summary>
///创建树
///<param name='nodes'>初始要加载的节点(节点的数组,可以使用js字面量也可以用数组:[{"ID":"1", "Name":"Node"}])</param>
///</summary>
BuildTree : function( nodes,parentNode )
{
if( nodes && nodes.length > 0 )
{
//Level 1
for( var i = 0; i < nodes.length ; i++ )
{
var oNode = this._BuildNode ( nodes[i],( i == nodes.length - 1 )? true : false, parentNode );
this._Fragment.appendChild( oNode );
if( nodes[i].HasChild )//如果有子节点
{
var childNodes = nodes[i].ChildNodes;
this.BuildTree(childNodes, oNode );
}
}
}
},
///<summary>
///创建节点
///<param name="node">节点对象(可以是js字面量,也可以是一般的对象)</param>
///<param name="isLast">判断节点是否为同级的最后一个</param>
///<param name="parentNode">父节点</param>
///</summary>
_BuildNode : function( node , isLast, parentNode)
{
if( node )
{
var oNode = document.createElement("div");
oNode.style.height = this.Styles.NodeHeight;
//节点的完整路径,存储从最上层的节点一直到本节点的Index,是为了方便按照level来寻找节点对应level的祖先节点
var nodePath = new Array();
if( parentNode && parentNode.NodePath && parentNode.NodePath.length > 0)
{
for( var i = 0; i <= parentNode.NodePath.length - 1; i++ )
{
nodePath.push(parentNode.NodePath[i]);
}
}
nodePath.push( this._Index);
oNode.NodePath = nodePath;
//构造相对于父节点的连接线
for( var i = 1; i < node.Level; i++ )
{
var ancestorNode =this._Nodes[nodePath[i-1]];
var oImg = document.createElement("img");
oImg.src = ancestorNode.IsLast ? this.Resources.Images.Lines.Blank : this.Resources.Images.Lines.ElbowLine ;
oNode.appendChild(oImg);
}
//构造节点本身的连接线
var elbowImg = document.createElement( "img" );
var elbowImgUrl = this.Resources.Images.Lines.Elbow;
if( isLast )//是同级的最后一个节点,则添加elbow-end.gif
{
elbowImgUrl = this.Resources.Images.Lines.ElbowEnd;
}
elbowImg .src = elbowImgUrl;
oNode.appendChild( elbowImg );
//构造节点类型图片
var imgUrl = this.Resources.Images.TrunkNode.Collapsed;
if( node.IsLeaf )
{
imgUrl = this.Resources.Images.LeafNode;
}
var nodeTypeImg = document.createElement( "img" );
nodeTypeImg.src = imgUrl;
oNode.appendChild( nodeTypeImg );
//节点名字
var oSpan = document.createElement("span");
oSpan.innerText = node.Name;
oSpan.textContent= node.Name;
oNode.appendChild( oSpan );
oNode.Index = this._Index;
oNode.ParentNodeIndex = parentNode?parentNode.Index : null;
oNode.IsLast = isLast;
oNode.IsLeaf = node.IsLeaf;
oNode.Level = node.Level;
this._Nodes[this._Index] = oNode;
this._Index++;
return oNode;
}
},
_Index : 1,
_Fragment : document.createDocumentFragment(),
_Nodes : new Array()
}
</script>
</head>
<body><div id="test"">
</div>
<script type="text/javascript">
var oDiv = document.getElementById("test");
var nodes = [{"Name":"计算机",IsLeaf:false,"Level":1,"HasChild":true, ChildNodes:[{"Name":"编程语言","Level":2,IsLeaf:false,"HasChild":true,ChildNodes:[{"Name":"C语言","Level":3,"IsLeaf":false,"HasChild":true,ChildNodes:[{"Name":"C语言程序设计","Level":4,"IsLeaf":true}]},{"Name":"C#语言","Level":3,"IsLeaf":true}]},{"Name":"设计模式","Level":2,IsLeaf:true}]},{"Name":"数学","Level":1,IsLeaf:false},{"Name":"社会学","Level":1,IsLeaf:false}];
Tree.BuildTree ( nodes );
oDiv.appendChild( Tree._Fragment );
</script>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<style type="text/css">
body
{
font-size:12px;
font-family:微软雅黑;
}
</style>
<script type="text/javascript" src="jquery-1.3.2-vsdoc2.js"></script>
<script type="text/javascript">
var Tree =
{
Resources :
{
Images :
{
TrunkNode :
{
Expanded : "images/folder-open.gif",
Collapsed: "images/folder.gif"
},
LeafNode : "images/leaf.gif",
Lines :
{
Elbow : "images/elbow.gif",
ElbowEnd : "images/elbow-end.gif",
ElbowLine :"images/elbow-line.gif",
Blank : "images/blank.gif"
}
}
},
Styles :
{
NodeHeight : "16px"
},
///<summary>
///创建树
///<param name='nodes'>初始要加载的节点(节点的数组,可以使用js字面量也可以用数组:[{"ID":"1", "Name":"Node"}])</param>
///</summary>
BuildTree : function( nodes,parentNode )
{
if( nodes && nodes.length > 0 )
{
//Level 1
for( var i = 0; i < nodes.length ; i++ )
{
var oNode = this._BuildNode ( nodes[i],( i == nodes.length - 1 )? true : false, parentNode );
this._Fragment.appendChild( oNode );
if( nodes[i].HasChild )//如果有子节点
{
var childNodes = nodes[i].ChildNodes;
this.BuildTree(childNodes, oNode );
}
}
}
},
///<summary>
///创建节点
///<param name="node">节点对象(可以是js字面量,也可以是一般的对象)</param>
///<param name="isLast">判断节点是否为同级的最后一个</param>
///<param name="parentNode">父节点</param>
///</summary>
_BuildNode : function( node , isLast, parentNode)
{
if( node )
{
var oNode = document.createElement("div");
oNode.style.height = this.Styles.NodeHeight;
//节点的完整路径,存储从最上层的节点一直到本节点的Index,是为了方便按照level来寻找节点对应level的祖先节点
var nodePath = new Array();
if( parentNode && parentNode.NodePath && parentNode.NodePath.length > 0)
{
for( var i = 0; i <= parentNode.NodePath.length - 1; i++ )
{
nodePath.push(parentNode.NodePath[i]);
}
}
nodePath.push( this._Index);
oNode.NodePath = nodePath;
//构造相对于父节点的连接线
for( var i = 1; i < node.Level; i++ )
{
var ancestorNode =this._Nodes[nodePath[i-1]];
var oImg = document.createElement("img");
oImg.src = ancestorNode.IsLast ? this.Resources.Images.Lines.Blank : this.Resources.Images.Lines.ElbowLine ;
oNode.appendChild(oImg);
}
//构造节点本身的连接线
var elbowImg = document.createElement( "img" );
var elbowImgUrl = this.Resources.Images.Lines.Elbow;
if( isLast )//是同级的最后一个节点,则添加elbow-end.gif
{
elbowImgUrl = this.Resources.Images.Lines.ElbowEnd;
}
elbowImg .src = elbowImgUrl;
oNode.appendChild( elbowImg );
//构造节点类型图片
var imgUrl = this.Resources.Images.TrunkNode.Collapsed;
if( node.IsLeaf )
{
imgUrl = this.Resources.Images.LeafNode;
}
var nodeTypeImg = document.createElement( "img" );
nodeTypeImg.src = imgUrl;
oNode.appendChild( nodeTypeImg );
//节点名字
var oSpan = document.createElement("span");
oSpan.innerText = node.Name;
oSpan.textContent= node.Name;
oNode.appendChild( oSpan );
oNode.Index = this._Index;
oNode.ParentNodeIndex = parentNode?parentNode.Index : null;
oNode.IsLast = isLast;
oNode.IsLeaf = node.IsLeaf;
oNode.Level = node.Level;
this._Nodes[this._Index] = oNode;
this._Index++;
return oNode;
}
},
_Index : 1,
_Fragment : document.createDocumentFragment(),
_Nodes : new Array()
}
</script>
</head>
<body><div id="test"">
</div>
<script type="text/javascript">
var oDiv = document.getElementById("test");
var nodes = [{"Name":"计算机",IsLeaf:false,"Level":1,"HasChild":true, ChildNodes:[{"Name":"编程语言","Level":2,IsLeaf:false,"HasChild":true,ChildNodes:[{"Name":"C语言","Level":3,"IsLeaf":false,"HasChild":true,ChildNodes:[{"Name":"C语言程序设计","Level":4,"IsLeaf":true}]},{"Name":"C#语言","Level":3,"IsLeaf":true}]},{"Name":"设计模式","Level":2,IsLeaf:true}]},{"Name":"数学","Level":1,IsLeaf:false},{"Name":"社会学","Level":1,IsLeaf:false}];
Tree.BuildTree ( nodes );
oDiv.appendChild( Tree._Fragment );
</script>
</body>
</html>