纯js,编写树形结构

先看下效果图

 直接上代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="container">

    </div>
</body>
<style>
    .containerParent {
        display: flex;
        flex-direction: column;
        width: auto;
    }

    .containerChildren {
        margin-left: 15px;
        width: 300px;
        border-left-style: dotted;
        border-color: #D8D8D8;
    }

    .parentChild {
        width: 300px;
    }

    .operaion_row-button {
        display: inline-block;
        min-width: 50px;
    }

    .editContainer {
        display: inline-block;
        padding-left: 10px;
        padding-right: 10px;
        width: 100px;
        height: 20px;
        max-width: 100px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap
    }

    .editContainer:focus {
        color: goldenrod;
    }

    .Icon_class {
        width: 15px;
        height: 15px;
    }

    .parentIcon {
        margin-left: 10px;
    }

    .parent_span {
        margin-left: 10px;
    }

    .descriter {
        display: inline-block;
        margin-top: -3px;
        color: #D8D8D8;
        vertical-align: top;
    }

    .focusClass {
        color: blue;
    }
</style>
<script>
    // 源数据
    const data = [
        {
            id: 1,
            name: "高配室",
            spread: true,
            tempChildren: [],
            children: [
                {
                    id: 2,
                    name: "第一个子节点",
                    edit: false,
                    checked: false,
                    children: [
                        {
                            id: 8,
                            edit: false,
                            checked: false,
                            name: "孙子节点",
                            children: []
                        },
                    ]
                },
                {
                    id: 5,
                    name: "第二个子节点",
                    checked: false,
                    edit: false,
                    children: []
                },
            ]
        }
    ];
    // 收集数据
    const arrId = [];

    // 切换子树中的显示状态
    function toggleFnc(val) {
        data.map(currentData => {
            if (currentData.id == val) {
                let temCuttentchildren = currentData.children;
                let temCuttenttempChildren = currentData.tempChildren;

                currentData.children = temCuttenttempChildren
                currentData.tempChildren = temCuttentchildren;

                currentData.spread = !currentData.spread
            }
        })
        container.innerHTML = getParent(data);
    };

    // 切换选中状态

    function toggleStatus(data, status) {
        if (data.children.length > 0) {
            data.children.map(currentData => {
                currentData.checked = status;
                if (currentData.children.length > 0) {
                    toggleStatus(currentData, status);
                }
            })
        }
    };

    // 获取选中数据,切换选中状态
    function toogleChecked(data, val, isInit) {
        data.map(currentData => {
            if (currentData.id == val) {
                currentData.checked = !currentData.checked;
                if (currentData.checked) {
                    arrId.push(currentData.name);
                    toggleStatus(currentData, true);
                } else {
                    let index = arrId.indexOf(currentData.name);
                    arrId.splice(index, 1);
                    toggleStatus(currentData, false);
                }

            } else if (currentData.children.length > 0) {
                toogleChecked(currentData.children, val, "NoInit");
            }
        })
    };

    // 获取选中数据,切换选中状态,刷新数据

    function selectionFunc(id,checked) {
        toogleChecked(data, id);
        container.innerHTML = getParent(data);
        let EleColor = document.getElementById(id).classList;
        if (!checked) {
            EleColor.add("focusClass");
        } else {
            EleColor.remove("focusClass");
        }
    }

    //   确认数据,规范化参数,
    function ascertainVaL(data, val, inpuId) {
        console.log("val", val, "inpuId", inpuId)
        data.map((currentData) => {
            if (currentData.id == val) {
                currentData.edit = false;
                if (inpuId.textContent == "") {
                    inpuId.textContent = "默认值"
                }
                currentData.name = inpuId.textContent;
            } else if (currentData.children.length > 0) {
                ascertainVaL(currentData.children, val, inpuId);
            }
        })
    };

    // 确定数据,刷新页面
    function ascertain(val) {
        let inpuId = document.getElementById(val);
        console.log("val", val);
        ascertainVaL(data, val, inpuId);
        container.innerHTML = getParent(data);
    };

    //生成默认数据,把数据加入源数据
    function addVal(data, val, randomId) {
        data.map((currentData) => {
            if (currentData.id == val) {

                let temObj = {
                    id: randomId,
                    name: "默认值",
                    edit: true,
                    children: []
                };

                currentData.children.push(temObj);
            } else if (currentData.children.length > 0) {
                addVal(currentData.children, val, randomId);
            }
        })
        console.warn("randomId", randomId)
        return randomId;
    };

    // 新建数据,把数据加入源数据,刷新页面
    function add(val) {
        let randomId = val + Math.ceil(Math.random(9999) * 10000) + 1000;
        let targetId = addVal(data, val, randomId);
        container.innerHTML = getParent(data);
        document.getElementById(targetId).focus();
    }

    // 删除数据
    function remove(val) {
        let removeVal = function (data) {
            data.map(currentData => {
                if (currentData.id == val) {
                    currentData.id = 9999;
                } else if (currentData.children.length > 0) {
                    removeVal(currentData.children);
                }
            })
        }
        removeVal(data);
        container.innerHTML = getParent(data);
    }


    // 获取父级数据
    function getParent(currentData) {
        if (currentData.id == "") return;
        let html = "";
        currentData.map(data => {
            let htmlValue = "";
            if (data.id != 9999) {
                htmlValue = `
          <div class= "containerParent">
            <div class="parentChild">
              <img  src = ${data.spread == true ? "./imgs/free.svg" : "./imgs/shrink.svg"}  alt="切换是否显示图标" class="Icon_class" onclick = ${`"toggleFnc(${data.id})"`} />
              <span data-appid=${data.id} class="parent_span">${data.name}</span>
              <img  src = "./imgs/add.svg"  alt="新增按钮" class="Icon_class parentIcon" onclick = ${`"add(${data.id})"`} />
            </div>
            ${data.children && data.children.length > 0 ? getChildren(data.children) : ""}
          </div>
        `
            }


            html += htmlValue;
        })

        return html;
    }


    //    获取子树数据
    function getChildren(data) {
        let currentData;
        let html = "";
        if (data.id == "" || data.id == 9999) return html;
        data.map((cuttentDate) => {
            if (cuttentDate.id == 9999) return html;
            let htmlValue
            if (cuttentDate.id) {
                let spanVal = `<img  src = "./imgs/define.svg"  alt="确定按钮" class="Icon_class" onclick = ascertain(${cuttentDate.id})>`;
                let inputClick = cuttentDate.id + "checkbox"
                htmlValue =
                    `
          <div class="containerChildren">
                 <span class="descriter">...</span>
                 ${cuttentDate.checked == true ?
                        `<img  src = "./imgs/checked.svg" onclick = ${`"selectionFunc(${cuttentDate.id},${cuttentDate.checked})"`}  id=${inputClick} alt="选中按钮" class="Icon_class" >` :
                        `<img  src = "./imgs/unChecked.svg" onclick = ${`"selectionFunc(${cuttentDate.id},${cuttentDate.checked})"`}  id=${inputClick} alt="不选中按钮" class="Icon_class">`
                    }
        
             <span id=${cuttentDate.id} contenteditable = ${cuttentDate["edit"]} class="editContainer" title=${cuttentDate.name}>${cuttentDate.name}</span>
              ${cuttentDate.edit == false ? "" : spanVal}
     
              <img  src = "./imgs/add.svg"  alt="新增按钮" class="Icon_class" onclick = ${`"add(${cuttentDate.id})"`}>
              <img  src = "./imgs/remove.svg"  alt="删除按钮" class="Icon_class" onclick = ${`"remove(${cuttentDate.id})"`}>
            
            ${cuttentDate.children && cuttentDate.children.length > 0 ? getChildren(cuttentDate.children) : ""}
          </div >
          
        `
            }
            html += htmlValue
        })

        return html
    }


    //双击触发事件
    function dbClickFnc(e) {
        let targetValue = (e.targetValue || e.srcElement).id;
        if (targetValue) {
            let getData = function (data) {
                data.map(currentData => {
                    if (currentData.id == targetValue) {
                        if (e.type == 'focusout') {
                            currentData.edit = false;
                        } else {
                            currentData.edit = true;
                        }

                    } else if (currentData.children.length > 0) {
                        getData(currentData.children);
                    }
                }
                )
            }
            getData(data);
            container.innerHTML = getParent(data);
            let getEle = document.getElementById(targetValue);
            getEle.focus();
        }

    }




    const container = document.getElementById("container");
    container.addEventListener("dblclick", dbClickFnc, false)
    container.innerHTML = getParent(data);





</script>

</html>

  

 

猜你喜欢

转载自www.cnblogs.com/wpw1215/p/12021521.html