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())

解决方案 »

  1.   


    呵呵,老兄是js高手,求教了我是想做一个和CSDN一样的用数组生成的树(修改别人的),在生成前置图标时生在了难点就是节点前置空格图片和|图片如何判断生成?
      

  2.   


    呵呵,老兄是js高手,求教了我是想做一个和CSDN一样的用数组生成的树(修改别人的),在生成前置图标时生在了难点就是节点前置空格图片和|图片如何判断生成?
      

  3.   

    树的话虑树的结构是最主要的一般产生的空白都不是使用空格来填充,而是使用css的pading或者margin来生成
      

  4.   

    主要是想要一个函数,判断标题前空白部分和|部分的可能交替输出我的想法是这样的:如果该节点有子节,则输出子节点时前面是空白还是|,要判断,判断如下:如果本节点下面有兄弟节点:则输出子节点时,在这级别上,输出|,滞则输出空白,
    同理,这也要一级一级向上递归判断,即判断:
    如果上一级节点下面仍有兄递节点,则输出|;否则输空白比如一个节点路径是这样的0--2-5-9,这个路径共有四级:
    输出第五级时判断:前三级(直至根目):每一级是否是最后一个节点:比如:在第二级中,2不是最后,则为0,5不是同级中最后一个,则为1最后根据01000111这栏的顺用图片或CSS替换:所以需要一函数:给一个索引号:一级一级向上判断并输出标识符!返回可向上面一样:在字中的位置表示级:0,在同级中位于最后;1表示不在同级中不排在最后这样即可生成和CSDN或资源管理器一样的树!没学过算法,搞了两天,感觉思路基本上理清了!  如果成功:一页代码,可生成CSDN树!
      

  5.   

    dhgdmw那你的多维数级是如何定义的,能超过二维?明天结贴!
      

  6.   

    这个虽然我没有做过,但我还是要接分……
    我想,如果只凭借父子节点,麻烦的就是需要两个算法,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>
      

  7.   

    已做完了,和CSDN的一样
    感谢上面的各位的参予了!showbo的js类写的很标准!
    加了两个函数,说一下思路了,有兴趣的可以自已研究:第一个:给一个节点号,判断是否在同级中最后,如果是,return ture,否则为false
    第二个:遍历父节点:很简单的parent=menuArr[parent][1],向上循环!
         
    下面就可以输出前置图标了!