输出一个多级菜单,能支持点击父菜单收起或展开子菜单,数据结构如下

79 阅读1分钟
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="list"></div>
</body>
<script>
    function getTree() {
        let defMap = [
            { id: 1, name: "旅游", pid: 0 },
            { id: 2, name: "国外", pid: 1 },
            { id: 3, name: "国内", pid: 1 },
            { id: 4, name: "泰国", pid: 2 },
            { id: 5, name: "租车", pid: 0 },
            { id: 6, name: "海外租车", pid: 5 },
            { id: 7, name: "SUV", pid: 6 },
            { id: 8, name: "紧凑", pid: 6 },
        ]

        let map = new Map(), tree = [], obj = {};
        defMap.forEach(val => {
            if (map.has(val.pid)) {
                let par = map.get(val.pid);
                let temp = {
                    id: val.id,
                    name: val.name,
                    child: []
                }
                par.child.push(temp);
                map.set(val.id, temp);
            } else {
                map.set(val.id, {
                    id: val.id,
                    name: val.name,
                    child: []
                });
                tree.push(map.get(val.id));
            }
        });
        return tree;
    }

    function createList(node, level) {
        const item = `<span id=${node.id} style="cursor: pointer; margin-left:${level}px">-</span>
            &nbsp<i>${node.name}</i>`;
        let dom = document.createElement('div');
        dom.insertAdjacentHTML('beforeend', item);
        return dom;
    }

    function triggle(event) {
        if (!event || !event.target || !(event.target.textContent==='+' || event.target.textContent==='-')) {
            return;
        }
        let target = event.target, curr = event.target.parentNode;
        if (!curr) {
            return;
        }
        let childs = curr.childNodes;
        if (target.textContent === '+') {
            target.innerHTML = '-';
            for(let i=3; i<childs.length; i++){
                childs[i].style.display = '';
            }
        } else {
            target.innerHTML = '+';
            for(let i=3; i<childs.length; i++){
                childs[i].style.display = 'none';
            }
        }
        console.log(event);
    }

    let root = document.querySelector('#list');
    const tree = getTree();
    const painting = (nodeList, parent, level) => {
        nodeList.forEach(val => {
            const curr = createList(val, level);
            parent.appendChild(curr);
            if (val.child.length > 0) {
                painting(val.child, curr, level + 15);
            }
        })
    }

    painting(tree, root, 0);

    root.addEventListener("click", triggle, true);
</script>
</html>```