var menuArr = new Array();
//索引,名称,父节点号
menuArr[1] = ["中国", 0];
menuArr[2] = ["美国", 0];
menuArr[3] = ["日本", 0];
menuArr[4] = ["浙江", 1];
menuArr[5] = ["福建", 1];
menuArr[6] = ["东京", 3];
menuArr[7] = ["杭州", 4];
menuArr[8] = ["温州", 4];
menuArr[9] = ["鹿城", 8];
menuArr[10] = ["广西", 1];
//=============================================
function lookThrough(Arr){
this.Arr=Arr;
this.splitArrayByPId();//分类节点
}
lookThrough.prototype.reset=function(str){
this.level=str?str:1;//第几级
this.endNode=str?str:false;//是否同级的末尾
this.path=str?str:new Array();//清空路径或者设置错误信息,注意此时存储的路径是当前节点到父节点,所以最后需要反转
this.wordPath=str?str:new Array();
}
lookThrough.prototype.toString=function(){
return "该节点在树中等级:"+this.level
+"\n\n该节点是否在末尾:"+this.endNode
+"\n\n路径:"+(typeof(this.path.join)!="undefined"?this.path.join("=>"):this.path)
+"\n\n文字路径:"+(typeof(this.wordPath.join)!="undefined"?this.wordPath.join("=>"):this.wordPath);
}
lookThrough.prototype.getWordPath=function(){
if(typeof(this.path)=="string")return;
var item;
for(var i=0;i<this.path.length;i++){
item=this.Arr[this.path[i]]
this.wordPath.push(item?item[0]:"根");
}
}
lookThrough.prototype.splitArrayByPId=function(){
this.Level=[];
var item;
for(var i=0;i<this.Arr.length;i++){
item=this.Arr[i];
if(!item)continue;//过滤数组中未使用的索引
if(!this.Level[item[1]])this.Level[item[1]]=new Array();
this.Level[item[1]].push({mIndex:i});
}
}
lookThrough.prototype.getLevelAndPath=function(Index){
var pId=this.Arr[Index][1];
this.path.push(pId);
while(this.Arr[pId]){
pId=this.Arr[pId][1]
this.path.push(pId)
this.level++;
}
}
lookThrough.prototype.go=function(Index){
if(!this.Arr[Index]){
this.reset('给的索引号不正确或者未在数组中!');return;
}
this.reset();
this.path.push(Index);//推入当前节点
this.getLevelAndPath(Index);
this.path.reverse();//============反转
this.getWordPath();
var SameLevel=this.Level[this.Arr[Index][1]];//获取拥有同一个父节点号的数组
if(SameLevel[SameLevel.length-1].mIndex==Index)this.endNode=true;
else this.endNode=false;
}
//======================Test===========================
var o=new lookThrough(menuArr);
o.go(1)
alert(o.toString())o.go(10)
alert(o.toString())o.go(4)
alert(o.toString())o.go(7)
alert(o.toString())o.go(8)
alert(o.toString())o.go(20)
alert(o.toString())
//索引,名称,父节点号
menuArr[1] = ["中国", 0];
menuArr[2] = ["美国", 0];
menuArr[3] = ["日本", 0];
menuArr[4] = ["浙江", 1];
menuArr[5] = ["福建", 1];
menuArr[6] = ["东京", 3];
menuArr[7] = ["杭州", 4];
menuArr[8] = ["温州", 4];
menuArr[9] = ["鹿城", 8];
menuArr[10] = ["广西", 1];
//=============================================
function lookThrough(Arr){
this.Arr=Arr;
this.splitArrayByPId();//分类节点
}
lookThrough.prototype.reset=function(str){
this.level=str?str:1;//第几级
this.endNode=str?str:false;//是否同级的末尾
this.path=str?str:new Array();//清空路径或者设置错误信息,注意此时存储的路径是当前节点到父节点,所以最后需要反转
this.wordPath=str?str:new Array();
}
lookThrough.prototype.toString=function(){
return "该节点在树中等级:"+this.level
+"\n\n该节点是否在末尾:"+this.endNode
+"\n\n路径:"+(typeof(this.path.join)!="undefined"?this.path.join("=>"):this.path)
+"\n\n文字路径:"+(typeof(this.wordPath.join)!="undefined"?this.wordPath.join("=>"):this.wordPath);
}
lookThrough.prototype.getWordPath=function(){
if(typeof(this.path)=="string")return;
var item;
for(var i=0;i<this.path.length;i++){
item=this.Arr[this.path[i]]
this.wordPath.push(item?item[0]:"根");
}
}
lookThrough.prototype.splitArrayByPId=function(){
this.Level=[];
var item;
for(var i=0;i<this.Arr.length;i++){
item=this.Arr[i];
if(!item)continue;//过滤数组中未使用的索引
if(!this.Level[item[1]])this.Level[item[1]]=new Array();
this.Level[item[1]].push({mIndex:i});
}
}
lookThrough.prototype.getLevelAndPath=function(Index){
var pId=this.Arr[Index][1];
this.path.push(pId);
while(this.Arr[pId]){
pId=this.Arr[pId][1]
this.path.push(pId)
this.level++;
}
}
lookThrough.prototype.go=function(Index){
if(!this.Arr[Index]){
this.reset('给的索引号不正确或者未在数组中!');return;
}
this.reset();
this.path.push(Index);//推入当前节点
this.getLevelAndPath(Index);
this.path.reverse();//============反转
this.getWordPath();
var SameLevel=this.Level[this.Arr[Index][1]];//获取拥有同一个父节点号的数组
if(SameLevel[SameLevel.length-1].mIndex==Index)this.endNode=true;
else this.endNode=false;
}
//======================Test===========================
var o=new lookThrough(menuArr);
o.go(1)
alert(o.toString())o.go(10)
alert(o.toString())o.go(4)
alert(o.toString())o.go(7)
alert(o.toString())o.go(8)
alert(o.toString())o.go(20)
alert(o.toString())
呵呵,老兄是js高手,求教了我是想做一个和CSDN一样的用数组生成的树(修改别人的),在生成前置图标时生在了难点就是节点前置空格图片和|图片如何判断生成?
呵呵,老兄是js高手,求教了我是想做一个和CSDN一样的用数组生成的树(修改别人的),在生成前置图标时生在了难点就是节点前置空格图片和|图片如何判断生成?
同理,这也要一级一级向上递归判断,即判断:
如果上一级节点下面仍有兄递节点,则输出|;否则输空白比如一个节点路径是这样的0--2-5-9,这个路径共有四级:
输出第五级时判断:前三级(直至根目):每一级是否是最后一个节点:比如:在第二级中,2不是最后,则为0,5不是同级中最后一个,则为1最后根据01000111这栏的顺用图片或CSS替换:所以需要一函数:给一个索引号:一级一级向上判断并输出标识符!返回可向上面一样:在字中的位置表示级:0,在同级中位于最后;1表示不在同级中不排在最后这样即可生成和CSDN或资源管理器一样的树!没学过算法,搞了两天,感觉思路基本上理清了! 如果成功:一页代码,可生成CSDN树!
我想,如果只凭借父子节点,麻烦的就是需要两个算法,1个得到当前节点,距离根节点的级别,就是他到底有几个父节点,个数作为前置输出的空白数量,
另外要一个获得当前节点的是否有子节点,如果有产生文件加图片,没有就是文件图片,如果有还要递归每个子节点
如果上述两个值都已经知道了,那不就爽了吗,所以……
当然当然,如果数据库不是这么设计的,相当于把2个算法交给php完成,然后输出js,这个也不能说这样就很差……
当然当然,如果说象下面那样,那怎么找出某个节点的父结点,这个问题很好……那就不得不高个算法,遍历数组,看看某个节点是否在 "子节点id"中,如果在的话,当前被遍历的就是父结点啦……
这也太差了吧,是阿,如果想在偷懒点,可以在 "子节点id" 后再加个 "父结点id",我靠……
我不得不说这样一句话,如果还是有人反对这样做的话,其实这样做,和楼主的0--2-5-9 是类似的,用一种编码,替代了算法,救命啊……<script>
var menuArr = new Array();
//本节点id,本节点名称,级别,子节点id
menuArr[1] = ["中国", 0,'7,9'];
menuArr[3] = ["美国", 0,''];
menuArr[5] = ["日本", 0,'22'];
menuArr[7] = ["浙江", 1,'32,42'];
menuArr[9] = ["福建", 1,''];
menuArr[22] = ["东京", 1,''];
menuArr[32] = ["杭州", 2,''];
menuArr[42] = ["温州", 2,'52'];
menuArr[52] = ["鹿城", 3,'']; var use=new Array();
for(var key in menuArr){
a(key);
}
function a(id) {
if(use[id]){
return ;
}else{
use[id]=true;
} for(var i=0;i<menuArr[id][1];i++){
document.write(' - ');//生成前置
} if(menuArr[id][2]==''){
document.write('!');//生成文件标记
document.write(menuArr[id][0]+"<br>");
}else{
document.write('#');//生成文件夹标记
document.write(menuArr[id][0]+"<br>"); var ing=menuArr[id][2].split(",");
for(var t in ing){
a(ing[t]);
}
}
}
</script>
感谢上面的各位的参予了!showbo的js类写的很标准!
加了两个函数,说一下思路了,有兴趣的可以自已研究:第一个:给一个节点号,判断是否在同级中最后,如果是,return ture,否则为false
第二个:遍历父节点:很简单的parent=menuArr[parent][1],向上循环!
下面就可以输出前置图标了!