一颗面向对象的javaScript树
来源:互联网 发布:数据港董事长周群 编辑:程序博客网 时间:2024/06/01 13:41
首先声明这颗树是根据project_tree_pub 修改 。
先来两个从prototype.js中抄袭过来的代码
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
function emptyFunction() {}
长期写Java代码,突然转到javascript,发现程序不那么好写,想来想去是javascript少了java.util.*包里面的类,
于是用javascript实现了List,Map两个类,这棵树只用到了List类,List类在我另外写的一个AjaxServer类里面可以转换成XML,然后传送给服务器端解析成java.util.ArrayList类,并且完美的嵌入了struts框架
/* List类
服务器端解析成java.util.ArrayList
*/
List =Class.create();
List.prototype={
initialize: function(){
this.className='java.util.ArrayList';
this._data=null;
this._data=new Array;
this._size=0;
},
size:function(){
return this._size;
},
indexOf:function(key){
var index=-1;
var i=0;
for(i=0;i<this._size;i++){
if(key==this._data[i]){
index=i;
break;
}
}
return index;
},
insert:function(index,key){
var i=0;
if(index>=this._size){
this._data[this._size]=key;
this._size++;
return;
}
for(i=this._size-1;i>this._size-index;i--){
this._data[i+1]=this._data[i];
}
this._data[index]=key;
},
add:function(key){
this.insert(this._size,key);
},
get:function(index){
if(index<0||index>=this._size)
return null;
return this._data[index];
},
remove:function(index){
var i=0;
if(index<0||index>=this._size)
return;
for(i=index;i<this._size-1;i++){
this._data[i]=this._data[i+1];
}
if(this._size>0)
this._data[this._size-1]=null;
this._size--;
},
clear:function(){
this.initialize();
}
}
下面是节点类,表示树的每一个节点,用List表示它的儿子们,_parentNode指向它的父亲,
_level表示节点所处在的层次,nodeID是节点的唯一标示,一颗树的每一个节点的ID必须唯一,这里在程序里面没有作控制^_^
_state 表示节点的状态,打开还是关闭的。
/*节点类*/
Node =Class.create();
Node.prototype={
/**构造函数
*节点id(必须唯一),节点显示名称,关联url,节点默认状态('open','closed')
*/
initialize:function(id,name,url,status){
this._children = new List();
this._url = url;
this._nodeID=id;
this._name=name;
this._state = status ;
this._level=0;
this._parentNode=null;
},
setParentNode:function(prentNode){
this._parentNode=prentNode;
},
getParent:function(){
return this._parentNode;
},
getChildren:function(){
return this._children;
},
getURL : function(){
return this._url;
},
getNodeID : function(){
return this._nodeID;
},
getName : function(){
return this._name;
},
getState : function(){
return this._state;
},
setState : function(state){
this._state=state;
},
getLevel : function(){
return this._level;
},
/**设置状态*/
setState : function(status){
this._state=status;
},
/**设置URL*/
setUrl : function(url){
this._url=url;
},
/**删除一个字节点*/
removeChild:function(nodeID){
var i=0;
var node=null;
for(i=0;i<this._children.size();i++){
node=this._children.get(i);
if(node.getNodeID()==nodeID){
this._children.remove(i);
break;
}
}
},
/**设置儿子*/
setChildren : function(children){
var i=0;
if(children instanceof List){
this._children=children;
for(i=0;i<children.size();i++){
children.get(i).setParentNode(this);
this.setLevel(this._level);
}
}else{
alert('属性不对无法加入!');
}
},
/**添加一个儿子*/
addChildNode : function(childNode){
if(childNode==this){
alert('子节点不能是本身');
return;
}
if(childNode instanceof Node){
this._children.add(childNode);
this.setLevel(this._level);
childNode.setParentNode(this);
}else{
alert('属性不对无法加入!');
}
},
/**设置子节点级别*/
setLevel : function (level){
var i=0;
this._level=level;
for(i=0;i<this._children.size();i++){
this._children.get(i).setLevel(level+1);
}
},
/**获得节点类型*/
getNodeType:function(){
var type='leaf';
if( this._children.size()>0)
type='node';
return type;
}
}
下面来看Tree类,先来看看他的属性,nodeList是一个根节点的List,
_treeName表示在javascript里面定义树变量的名称,通过构造函数传入
currentNodeID当前选择的节点
onClick 初始化为空函数,用户要响应点击树节点事件,必须重载此函数
removeNode(nodeID) 删除一个节点
getNode(nodeID)根据节点编号找到Node对象
repaint()当树的结构发生变化时必须调用此方法重画树
getTree()获得定义树的HTML,只有初始化树时候调用,其它时候请调用repaint()重画树
/*********************树类***************/
Tree =Class.create();
Tree.prototype={
/**构造函数*/
initialize: function(treeName){
this.nodeList=new List();
this._outStr='';
this._treeName=treeName;
this.currentNodeID="";
this.onClick=emptyFunction;
/*是否采用异步请求的方式*/
this.isAsync=false;
},
splitChar : " ", //每个层次间的分隔符
img_opennode : "images/folderopen.gif",
img_node : "images/folder.gif",
img_leaf : "images/page.gif",
img_selnode : "images/foldersel.gif",
img_selopennode : "images/folderopensel.gif",
img_selleaf : "images/pagesel.gif",
img_nodeisclick : "images/open.gif",
img_nodenotclick : "images/plus.gif",
img_split : " ",
/**获得当前的节点*/
getCurrentNode:function(){
if(this.currentNodeID!=''){
return this.getNode(this.currentNodeID);
}
return null;
},
/**设置根节点*/
addRoot:function(root){
this.nodeList.add(root);
},
/**删除节点*/
removeNode : function(nodeID){
var i=0;
var node=this.getNode(nodeID);
if(node==null){
alert('找不到节点:'+nodeID);
return;
}
if(node.getParent()==null){
for(i=0;i<this.nodeList.size();i++){
if(this.nodeList.get(i).getNodeID()==nodeID){
this.nodeList.remove(i);
break;
}
}
}else{
node.getParent().removeChild(nodeID);
}
if(this.currentNodeID==nodeID)
this.currentNodeID='';
},
/**根据节点编号获得节点*/
getNode:function(nodeID){
var i=0;
var node=null;
for(i=0;i<this.nodeList.size();i++){
node=this.getChildNode(this.nodeList.get(i),nodeID);
if(node!=null)
break;
}
return node;
},
/**根据节点编号获得节点*/
getChildNode:function(node,nodeID){
var retNode=null;
var i=0;
if(node.getNodeID()==nodeID)
return node;
for(i=0;i<node.getChildren().size();i++){
retNode=this.getChildNode(node.getChildren().get(i),nodeID);
if(retNode!=null)
break;
}
return retNode;
},
/**重画树*/
repaint: function(){
this._outStr='';
for(i=0;i<this.nodeList.size();i++){
var node=this.nodeList.get(i);
this.printTree(node,'open',0);
}
document.getElementById("kuyuer_"+this._treeName).innerHTML=this._outStr;
},
/**生成树*/
getTree:function(){
var i=0;
this._outStr="<div id='kuyuer_"+this._treeName+"'>";
for(i=0;i<this.nodeList.size();i++){
var node=this.nodeList.get(i);
this.printTree(node,'open',0);
}
this._outStr+="</div>";
return this._outStr;
},
/*
* 输出整个树的页面展现字符串
*/
printTree:function (tempNode,parentStatus,level){
var i=0;
var childLength=tempNode.getChildren().size();
this._outStr=this._outStr+this.printNode(tempNode,parentStatus,level)
if(childLength>0){
for(i=0;i<childLength;i++){
this.printTree(tempNode.getChildren().get(i),tempNode.getState(),level+1);
}
}
this._outStr=this._outStr+"</div>";
} ,
/*
* 输出对应节点的页面展现字符串
* 参数说明:节点对应,父节点的节点状态
*/
printNode:function(tempNode,parentStatus,level){
var childLength=tempNode.getChildren().size();
var style_display="display:block";
var boundstr="";
var nodestr="";
var imgsrc="";
var imgstatus="";
/*父节点处于关闭状态,子结点包括其子节点都不显示*/
if(parentStatus=="closed")
style_display="display:none";
if(childLength>0){
if(tempNode.getState()=='open'){
imgsrc=this.img_opennode;
imgstatus=this.img_nodeisclick;
}
else{
imgsrc=this.img_node;
imgstatus=this.img_nodenotclick;
}
}else{
imgsrc=this.img_leaf;
}
for(j=0;j<level;j++){
boundstr += this.splitChar;
}
/*是结点*/
if(childLength>0){
nodestr="<div id='" + tempNode.getNodeID() +"' style='" + style_display+"' >"+boundstr
+"<img imgtype='status' onclick=/""+this._treeName+".nodeClick(this,'"+tempNode.getNodeID()+"')/" src='"+imgstatus+"' >"
+"<img imgtype='node' src=/""+imgsrc+"/" >" ;
if(tempNode.getURL()=='')
nodestr+=tempNode.getName();
else
nodestr+="<a style='cursor:hand' onclick=/""+this._treeName+".nameClick(this,'"+tempNode.getNodeID()+"')/">"
+ tempNode.getName()+"</a>";
}
/*树叶*/
else{
nodestr="<div id='" + tempNode.getNodeID() +"' style='" +style_display+"' >"+boundstr
+this.img_split+"<img src='"+imgsrc+"' imgtype='node' >";
if(tempNode.getURL()=='')
nodestr+=tempNode.getName();
else
nodestr+="<a style='cursor:hand' onclick=/""+this._treeName+".nameClick(this,'"+tempNode.getNodeID()+"')/">"
+ tempNode._name+"</a>";
}
return nodestr;
},
/*
* 根据id获取对应图层对象,解析页面子节点,更新点击后的节点图片和状态图片,更新对应子节点显示
*/
nodeClick:function(src,nodeid){
var obj=document.getElementById(nodeid);
var node=this.getNode(nodeid);
var childobj="";
var childlength=obj.childNodes.length;
/**节点状态*/
var nodestatus="";
/**是否取得了子节点*/
var synstus="no";
var nodesplitlength=0;
/*动态生成子节点*/
if(this.isAsync ){
/*对应节点的分隔符*/
nodesplitlength=obj.childNodes[0].nodeValue.length;
for(i=0;i<childlength;i++){
childobj=obj.childNodes[i];
if(childobj.tagName!=null){
if(childobj.tagName.toUpperCase()=="DIV"){
synstus="yes";
break;
}
}
}
/*尚未同步*/
if(synstus=="no"){
/*
*需要去服务器获得节点信息
*/
/*更新节点后重新获取子节点长度*/
childlength=obj.childNodes.length;
nodestatus="open";
}
else{
nodestatus="closed";
}
}
/*只有异步生成html或者不是异步生成的触发该事件*/
if(this.isAsync==false||synstus=="yes"){
for(i=0;i<childlength;i++){
childobj=obj.childNodes[i];
if(childobj.tagName!=null){
if(childobj.tagName.toUpperCase()=="DIV"){
if(childobj.style.display=="block"){
childobj.style.display="none";
nodestatus="closed";
}
else{
childobj.style.display="block";
nodestatus="open";
}
}
}
}
}
for(i=0;i<childlength;i++){
childobj=obj.childNodes[i];
if(childobj.tagName!=null){
if(childobj.tagName.toUpperCase()=="IMG"){
//if(event.srcElement==childobj){
if(src==childobj){
/*异步请求不需要再重新判断当前节点状态*/
if(synstus!="no"||this.isAsync==false){
if(nodestatus=="closed"){
childobj.src=this.img_nodenotclick;
}
else{
childobj.src=this.img_nodeisclick;
}
}
}
else{
if(nodestatus=="closed"){
/*如果是最近一次点击的节点*/
if(nodeid==this.currentNodeID){
childobj.src=this.img_selnode;
}
else{
childobj.src=this.img_node;
}
}
else{
if(childobj.imgtype=='node'){
/*如果是最近一次点击的节点*/
if(nodeid==this.currentNodeID){
childobj.src=this.img_selopennode;
}
else{
childobj.src=this.img_opennode;
}
}
}
}
}
}
}
//设置节点状态
if(node.getState()=='closed')
node.setState('open');
else
node.setState('closed');
},
/*设置点击时对应图标变化,标识当前节点
*主要实现功能点:
* 1、更新上次点击的节点的点击图片,如果是枝节点需要根据其状态选择更新的图片
* 2、设置当前点击的节点的点击图片,如果是枝节点需要根据其状态选择更新的图片
* 3、更新系统最近点击的节点类型、节点id
*/
nameClick:function(src,objID){
var obj=src;
var parNode= obj.parentNode;
var childobj="";
var lastobj=""
var lastNode=null;
var node=this.getNode(objID);
if(node.getURL()=='')
return;
/*取消上次点击的图片*/
if(this.currentNodeID!=""){
lastobj=document.getElementById(this.currentNodeID);
lastNode=this.getNode(tree.currentNodeID);
for(i=0;i<lastobj.childNodes.length;i++){
childobj = lastobj.childNodes[i];
if(childobj.tagName!=null){
if(childobj.tagName.toUpperCase()=="IMG" && childobj.imgtype=='node'){
if(lastNode.getNodeType()=="leaf"){
childobj.src=this.img_leaf;
}
if(lastNode.getNodeType()=="node"){
if(lastNode.getState()=="open"){
childobj.src=this.img_opennode;
}
else{
childobj.src=this.img_node;
}
}
}
}
}
}
this.currentNodeID=parNode.id;
for(i=parNode.childNodes.length;i>0;i--){
childobj = parNode.childNodes[i];
if(childobj!=null){
if(childobj.tagName!=null){
if(childobj.tagName.toUpperCase()=="IMG" && childobj.imgtype=='node'){
/*点击的为枝节点*/
if(node.getNodeType()=="node") {
if(node.getState()=="closed"){
childobj.src=this.img_selnode;
}
else{
childobj.src=this.img_selopennode;
}
}
/*点击的为叶节点*/
if(node.getNodeType()=="leaf"){
this.lastclicktype= childobj.imgtype;
childobj.src=this.img_selleaf;
}
}
}
}
}
this.onClick(node);
}
}
下面就来看看一颗树的例子
<html>
<head>
<script language="javascript">
var tree=new Tree("tree");
//点击节点
function treeClick(node){
alert('节点名称:'+node.getName()+'/n节点类型:'+node.getNodeType()+'/n节点级别:'+node.getLevel()+'/n节点URL:'+node.getURL());
if(node.getParent()!=null)
alert('父节点名称:'+node.getParent().getName());
}
//增加节点
function add(){
if(tree.getNode('AC')!=null){
alert('节点已经添加');
return ;
}
var node1=new Node('AC','不认识','AAAAAAAA','open');
var node= tree.getNode('A');
node.addChildNode(node1);
tree.repaint();
}
//删除节点
function remove(){
if(tree.getCurrentNode()==null)
return;
tree.removeNode(tree.getCurrentNode().getNodeID());
tree.repaint();
}
var rootNode=new Node('AA','我认识的人','http://www.baidd.com','open');
var node1=new Node('A','同事','A','open');
var nodeA1=new Node('AAA1','kuyuer','A','open');
node1.addChildNode(nodeA1);
var node2=new Node('B','同学','A','closed');
var node3=new Node('B1','唐海荣','A','open');
node2.addChildNode(node3);
var rootNode1=new Node('aaaa1','我的老师','http://www.baidu.com','closed');
var node11=new Node('CCCC','陈阿梦','http://www.china.com','open');
var node21=new Node('FFFF','陈天霸','A','open');
rootNode.addChildNode(node1);
rootNode.addChildNode(node2);
rootNode1.addChildNode(node11);
rootNode1.addChildNode(node21);
tree.addRoot(rootNode);
</script>
</head>
<body>
<INPUT TYPE="button" value="增加节点" onclick="add()">
<INPUT TYPE="button" value="删除节点" onclick="remove()"><br><br>
<script language="javascript">
treeValue=tree.getTree();
document.write(treeValue);
//响应Tree的onClick的事件
tree.onClick=treeClick;
</script>
</body>
</html>
- 一颗面向对象的javaScript树
- javascript复习一 JavaScript的面向对象
- javascript 面向对象(一)
- JavaScript面向对象(一)
- javaScript 面向对象一
- javascript面向对象(一)
- javascript的面向对象开发(一)
- 全面理解Javascript的面向对象(一)
- 全面理解Javascript的面向对象(一)
- 面向对象的JavaScript (一) ----- Javascript偏僻的基础知识
- 初学javascript面向对象(一)
- javascript 面向对象开发一
- Javascript面向对象基础一
- javaScript 面向对象-继承(一)
- JavaScript面向对象精要(一)
- JavaScript面向对象(一):封装
- javascript-面向对象(一)
- JavaScript面向对象精要(一)
- SQLServer2005中的增强数据类型VARCHAR(MAX)
- 微软MSDN上关于ARM芯片浮点运算的资料 Zz
- sql server 2005学习点滴(小知识点)
- DataGrid技巧大集合(转载)
- WPF,一次洗牌……
- 一颗面向对象的javaScript树
- JavaScript画图(转载)
- NOD32 ID及升级服务器
- Vocabulary4
- 类设计问题:保护和暴露
- 节目泛娱乐化
- gcc和g++的区别
- DataGrid使用心得
- javascript 播放器 控制