JavaScript递归菜单栏

HTML就一个div大框架

html 复制代码
 <div class="treemenu">

    </div>

重中之重的JavaScript部分他来啦!

注释也很清楚哟家人们!

javascript 复制代码
let data;
let arr = [];
let cons;

let xhr = new XMLHttpRequest();
// 设置请求方式和请求地址
xhr.open('get', './js/tree.json', true);
// 发送请求
xhr.send();
// 接收返回的响应数据
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
        data = JSON.parse(xhr.responseText);
        // 调用展示商品的函数
        // console.log(data);
        function inn(data, pid, arr) {
            for (let i = 0; i < data.length; i++) {
                if (data[i].pid == pid) {
                    // 递归调用,构建当前节点的子节点数组
                    data[i].children = inn(data, data[i].id, []);
                    // 将当前节点加入到父节点的 children 数组中
                    arr.push(data[i]);
                }
            }
            return arr;
        }
        arr = inn(data, 0, []);
        console.log(arr);
        rendertree(arr);

    }
};

function rendertree(data) {
    let str = `<div class="tree_wrap">`; // 开始构建树的容器

    for (let i = 0; i < data.length; i++) {
        if (data[i].children.length > 0) { // 如果当前节点有子节点
            str +=
                `<div onclick="show(this)" class="tree_flex"> 
                    <img src="${data[i].icon}" alt="" class="con">${data[i].name} 
                    <span><img src="./img/jtt.png" alt="" class="cons"></span>
                </div>
                <div style="display:none">`; // 添加可展开的节点和子节点的容器

            str += rendertree(data[i].children); // 递归渲染子节点

            str += `</div>`;
        } else { // 如果当前节点没有子节点
            str +=
                `<div class="tree_left">
                    <img src="${data[i].icon}" alt="" class="con">${data[i].name}
                </div>`; // 直接添加叶子节点
        }
    }

    str += `</div>`;    // 关闭树的容器
    document.getElementsByClassName('treemenu')[0].innerHTML = str; // 将整棵树渲染到页面上的指定位置
    return str; // 返回树的 HTML 字符串
}




// 获取所有类名为 'tree_left' 的元素集合
let tree_left = document.getElementsByClassName('tree_left');

// 定义展开或折叠子节点的函数
function show(obj) {
    let children = obj.nextElementSibling; // 获取当前节点的下一个兄弟元素,即子节点容器
    obj.querySelector('.cons').style.transition = "transform 1s"; // 设置箭头图标的过渡效果为1秒

    // 判断子节点容器的显示状态
    if (children.style.display == 'block') {
        // 如果子节点容器是显示的,则隐藏它
        children.style.display = 'none'; // 隐藏子节点容器
        obj.querySelector('.cons').style.transform = "rotate(0deg)"; // 将箭头图标旋转角度设为0度,折叠状态
    } else {
        // 如果子节点容器是隐藏的,则显示它
        children.style.display = 'block'; // 显示子节点容器
        obj.querySelector('.cons').style.transform = "rotate(180deg)"; // 将箭头图标旋转角度设为180度,展开状态
        obj.querySelector('.cons').style.transition = "transform 1s"; // 设置箭头图标的过渡效果为1秒
    }
}

CSS样式包含了彩色小背景!

css 复制代码
body {
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
    background-size: 400% 400%;
    animation: gradientAnimation 15s ease infinite;
    font-family: Arial, sans-serif;
    user-select: none;
}

@keyframes gradientAnimation {
    0% {
        background-position: 0% 50%;
    }

    50% {
        background-position: 100% 50%;
    }

    100% {
        background-position: 0% 50%;
    }
}


.treemenu {
    width: 30%;
    height: 700px;
    font-weight: 700;


}



.con {
    width: 15px;
    height: 15px;
    float: left;
    margin-top: 7px;
}


.tree_wrap {
    margin-left: 20px;
    line-height: 30px;
}

.tree_wrap :hover {
color: blue;
}



.cons {
    width: 15px;
    height: 15px;
    margin-left: 2%;
    margin-top: 7px;
}

样式图:

想要假数据的私我

相关推荐
小白冲鸭1 天前
苍穹外卖-前端环境搭建-nginx双击后网页打不开
运维·前端·nginx
wulijuan8886661 天前
Web Worker
前端·javascript
深念Y1 天前
仿B站项目 前端 3 首页 整体结构
前端·ai·vue·agent·bilibili·首页
IT_陈寒1 天前
React 18实战:这5个新特性让我的开发效率提升了40%
前端·人工智能·后端
深念Y1 天前
仿B站项目 前端 5 首页 标签栏
前端·vue·ai编程·bilibili·标签栏·trae·滚动栏
老朋友此林1 天前
React Hook原理速通笔记1(useEffect 原理、使用踩坑、渲染周期、依赖项)
javascript·笔记·react.js
克里斯蒂亚诺更新1 天前
vue3使用pinia替代vuex举例
前端·javascript·vue.js
Benny的老巢1 天前
用 Playwright 启动指定 Chrome 账号的本地浏览器, 复用原账号下的cookie信息
前端·chrome
毕设源码-朱学姐1 天前
【开题答辩全过程】以 日程管理系统为例,包含答辩的问题和答案
java
a努力。1 天前
京东Java面试被问:双亲委派模型被破坏的场景和原理
java·开发语言·后端·python·面试·linq