多级勾选框联动核心js

最近写了两次多级联动勾选框,有了点小心得,总结一下:

需求:

情形:当勾选/取消勾选框

1、其子集的框全部被勾选,当取消勾选框时,其子孙勾选框全部取消勾选;

2、其所有祖父级,若果检查到子孙级有被勾选的,需要将自身状态变成勾选状态,若没有被勾选的,则所有祖父级取消勾选转态

代码:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<script>
    let o = {
        status:false,
        child:[
            {
                status:true,
                child:[
                    {status:false,child:[]},
                    {status:false,child:[]},
                    {status:false,child:[]},
                ] 
            },
            {
                status:false,
                child:[
                    {status:false,child:[]},
                    {status:false,child:[]},
                    {status:false,child:[]},
                ] 
            },
            {
                status:false,
                child:[
                    {status:false,child:[]},
                    {status:false,child:[]},
                    {status:false,child:[]},
                ] 
            },
        ]
    };
    let a={};
    a.changeChildStatus = function(curParent){
    // 根据当前对象的状态 改变所有子集的状态
    //参数接收当前对象
        if(curParent.child && curParent.child.length>0){
            curParent.child.forEach(item=>{
                item.status = curParent.status;
                a.changeChildStatus(item);
                
            })
        }
    }
    a.allChildStatusArr = function(obj){
    // 获取当前对象下所有子集的状态 (递归)
    //参数接收当前对象
        let allChildArr = [];
        function getAllChildSatus(obj){
            if(obj.child && obj.child.length>0){
                obj.child.forEach(item=>{
                    allChildArr.push(item.status);
                    getAllChildSatus(item);
                })
            }
        }
        getAllChildSatus(obj)
        return allChildArr;
    }
    a.changeParentStatus = function(parentObj){
    // 根据子集状态改变父级状态 (递归)
    // 接收最大的对象
        parentObj.allChildStatusArr = a.allChildStatusArr(parentObj); 
        if(parentObj.allChildStatusArr.includes(true)){
            parentObj.status = true;
        }else if(parentObj.allChildStatusArr.every(item=>item == false) && parentObj.allChildStatusArr.length > 0){
            parentObj.status = false;
        }
        if(parentObj.child && parentObj.child.length>0){
            parentObj.child.forEach(item=>{
                a.changeParentStatus(item);
            })
        }
    }
    a.linked = function(bigObj,curObj,plies = 0){
    //联动总方法
    // 参数接收 最大对象,当前对象,层数
        a.changeChildStatus.call(curObj,curObj);//改变当前对象下子集的状态
        for(let i = 0;i < plies; i++){
        // 因为需要一层一层的改变父级状态,所以有几层,调用几次
            a.changeParentStatus.call(bigObj,bigObj);
        }
    }
    a.linked(o,o.child[0],3);//调用联动方法
    console.log(JSON.parse(JSON.stringify(o)));
</script>
</body>
</html>
复制代码

 

 

 

 

posted @   古墩古墩  Views(358)  Comments(0Edit  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示