js 树形菜单递归

本文详细探讨了如何使用JavaScript实现树形菜单的递归遍历和构建,涵盖了从数据结构的设计到递归函数的编写,帮助开发者理解递归在处理层次结构数据时的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<script>//数据结构  
    var json = [  
    { id: 1, pid: 0, text: '1(XX公司)' },  
    { id: 2, pid: 4, text: '2.1.1(开发部a-1组)' },  
    { id: 3, pid: 0, text: '2(开发部)' },  
    { id: 4, pid: 3, text: '2.1(开发部a)' },  
    { id: 5, pid: 0, text: '3(人事部)' },  
    { id: 6, pid: 5, text: '3.1(人事部A)' },  
    { id: 7, pid: 0, text: '4(设计部)' },  
    { id: 8, pid: 7, text: '4.1(设计部A)' },  
    { id: 9, pid: 4, text: '2.1.2(开发部a-2组)' },  
    { id: 11, pid: 2, text: '2.1.1.1(开发部a-1组>1小组)' },  
    { id: 12, pid: 2, text: '2.1.1.2(开发部a-1组>2小组)' },  
    { id: 13, pid: 5, text: '3.2(人事部A)' },  
    { id: 19, pid: 5, text: '3.3(人事部B)' }  
    ];  
    function departmentRecursion(mid, obj) {  
        var a = '<dl>'; 
        //console.log(obj.length); 
        //for (var i = 0, j=0;i<=obj.length;) 
        //{
           // console.log(i,j);
           // if (j.pid == mid)  
               // a += '<dt>' + j.text + '</dt><dd>' + departmentRecursion(j.id, obj) + '</dd>'; 
                // a += '<dt>' + j.text + '</dt><dd>' + departmentRecursion(j.id, obj) + '</dd>'; j = obj[i++]; 
       // }
        for(var i=0;i<obj.length;i++)
       {
        //console.log(obj[i].pid)
        if(obj[i].pid==mid)
         a += '<dt>' + obj[i].text + '</dt><dd>' + departmentRecursion(obj[i].id, obj) + '</dd>'; 
       }
        
        a += '</dl>';  
        return a;  
    }  
    document.write(departmentRecursion(0, json));  
</script>  
<script>

    var data = [
        {
            id:1,
            name :"一级分类:1",
            pid :0,
        },
        {
            id:2,
            name :"二级分类:1",
            pid :1,
        },
        {
            id:3,
            name :"三级分类:3",
            pid :2,
        },
        {
            id:4,
            name :"一级分类:2",
            pid :0,
        },
        {
            id:7,
            name :"f级分类:2",
            pid :4,
        },
        {
            id:10,
            name :"f级分类:2",
            pid :7,
        },
        {
            id:9,
            name :"f级分类:2",
            pid :10,
        },
        {
            id:12,
            name :"f级分类:2",
            pid :9,
        },
        {
            id:15,
            name :"f级分类:2",
            pid :12,
        },
        {
            id:13,
            name :"f级分类:2",
            pid :15,
        },
    ]



   function tree(data) {
        let map = {};
        let val = [];
        //生成数据对象集合
        data.forEach(it=>{
            map[it.id] = it;
        })
        //生成结果集
        data.forEach(it=>{
            const parent = map[it.pid];
            if(parent){
                if(!Array.isArray(parent.children)) parent.children = [];
                parent.children.push(it);
            }else{
                val.push(it);
            }
        })
        return val;
    }

    console.log(tree(data))


</script>
<script>
    function toTree(data) {
        // 删除 所有 children,以防止多次调用
        data.forEach(function (item) {
            delete item.children;
        });
 
        // 将数据存储为 以 id 为 KEY 的 map 索引数据列
        var map = {};
        data.forEach(function (item) {
            map[item.id] = item;
        });
//        console.log(map);
        var val = [];
        data.forEach(function (item) {
            // 以当前遍历项,的pid,去map对象中找到索引的id
            var parent = map[item.pid];
            // 好绕啊,如果找到索引,那么说明此项不在顶级当中,那么需要把此项添加到,他对应的父级中
            if (parent) {
                (parent.children || ( parent.children = [] )).push(item);
            } else {
                //如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中,作为顶级
                val.push(item);
            }
        });
        return val;
    }
    console.log(toTree(data))
</script>
//解析函数
function parseJson(arr){
    if(arr.length!=0){
        function pp(arr){
            for(var i=0;i<arr.length;i++){
                if(arr[i].children && arr[i].children.length!=0){
                    console.log(arr[i].name);//这里可以写菜单的样式结构...
                    pp(arr[i].children);
                }else{
                    console.log(arr[i].name);//这里可以写菜单的样式结构...
                }
            }
        }
        pp(arr);
    }
}
parseJson(arr);
//在网页中添加下拉框容器
<select id="selectbox" name=""></select>
//js脚本,递归生成
//获取容器对象
var selectbox=document.getElementById("selectbox");
 
//生成树下拉菜单
var j="-";//前缀符号,用于显示父子关系,这里可以使用其它符号
function creatSelectTree(d){
 var option="";
 for(var i=0;i<d.length;i++){
 if(d[i].children.length){//如果有子集
  option+="<option value='"+d[i].id+"'>"+j+d[i].name+"</option>";
 j+="-";//前缀符号加一个符号
  option+=creatSelectTree(d[i].children);//递归调用子集
 j=j.slice(0,j.length-1);//每次递归结束返回上级时,前缀符号需要减一个符号
  }else{//没有子集直接显示
  option+="<option value='"+d[i].id+"'>"+j+d[i].name+"</option>";
  }
  }
 return option;//返回最终html结果
 }
 
//调用函数,并将结构出入到下拉框容器中
selectbox.innerHTML=creatSelectTree(tree);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值