jQuery 实现可折叠树形菜单:从数据到交互的完整指南

一、需求分析

① 从 JSON 文件加载层级化菜单数据
②支持菜单折叠 / 展开,点击父项切换状态
③箭头图标随菜单状态旋转,直观反馈交互结果
④样式美观,层级结构清晰

二、实现步骤详解

1. 基础结构与样式搭建

首先创建 HTML 容器,定义菜单的基础样式,包括容器布局、菜单项间距、箭头图标样式及过渡效果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>树形菜单</title>
    <style>
        .box {
            width: 255px;
            background-color: #cfd9eb;
            border-radius: 10px;
            padding: 10px 0; /* 增加内边距,优化布局 */
        }
        .sub-menu {
            padding-left: 30px;
            margin: 0; /* 清除默认边距 */
            list-style: none; /* 去掉默认列表样式 */
        }
        .sub-item {
            line-height: 40px;
            cursor: pointer;
            width: 100%;
            font-size: 20px;
            padding: 0 10px; /* 增加左右内边距 */
        }
        .sub-item:hover {
            background-color: #b8c6db; /* hover效果,提升交互感 */
        }
        .sub-item img {
            width: 25px;
            height: 25px;
            vertical-align: middle;
            margin-left: 7px;
            transition: transform 0.3s ease; /* 箭头旋转过渡 */
        }
        .rotate {
            transform: rotate(180deg); /* 箭头旋转180度 */
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <!-- 引入jQuery -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
</body>
</html>

2. JSON 数据格式设计

创建json文件,用id标识节点唯一值,pid表示父节点 ID(根节点 pid 为 "0"),name为菜单名称,通过这三个字段实现层级关联。

[
    {"id": "1", "pid": "0", "name": "菜单1"},
    {"id": "1-1", "pid": "1", "name": "菜单1-1"},
    {"id": "1-2", "pid": "1", "name": "菜单1-2"},
    {"id": "1-2-1", "pid": "1-2", "name": "菜单1-2-1"},
    {"id": "2", "pid": "0", "name": "菜单2"},
    {"id": "2-1", "pid": "2", "name": "菜单2-1"},
    {"id": "3", "pid": "0", "name": "菜单3"}
]

3. AJAX 请求加载数据

使用 jQuery 的$.ajax()方法请求 JSON 文件,成功后获取数据并调用渲染函数,同时默认隐藏所有子菜单(初始只显示根节点)。

$(document).ready(function () {
    var menuData = [];
    // 发送AJAX请求获取菜单数据
    $.ajax({
        url: './js/07-树形菜单.json',
        type: 'GET',
        dataType: 'json',
        success: function (data) {
            menuData = data;
            renderMenu(data); // 调用渲染函数
            $(".box ul ul").hide(); // 初始隐藏所有子菜单
        },
        error: function (err) {
            console.error('菜单数据加载失败:', err);
        }
    });
});

4. 递归渲染层级菜单

树形菜单的核心是层级渲染,通过递归函数renderMenu,根据pid筛选当前节点的子节点,动态创建ulli元素,嵌套生成多级菜单。

// 渲染菜单函数:data-数据源,pid-父节点ID,$parent-父容器
function renderMenu(data, pid = "0", $parent = $(".box")) {
    // 筛选当前父节点的所有子节点
    var children = data.filter(item => item.pid === pid);
    if (children.length === 0) return; // 无子女节点则终止递归

    // 创建子菜单容器
    var $ul = $("<ul class='sub-menu'></ul>");
    $parent.append($ul);

    // 遍历子节点,创建菜单项
    children.forEach(item => {
        // 菜单项包含名称和箭头图标
        var $li = $("<li class='sub-item'></li>").html(`${item.name} <img src="./img/向下箭头.png" alt="切换">`);
        $ul.append($li);
        // 递归渲染当前节点的子菜单
        renderMenu(data, item.id, $li);
    });
}

5. 实现折叠 / 展开交互

为菜单项绑定点击事件,通过toggle()切换子菜单显示状态,用toggleClass("rotate")实现箭头旋转,同时通过e.stopPropagation()阻止事件冒泡(避免父节点联动触发)。

// 菜单点击事件:委托绑定(适配动态生成的节点)
$(".box").on("click", ".sub-item", function (e) {
    e.stopPropagation(); // 阻止事件冒泡
    var $childUl = $(this).children(".sub-menu"); // 获取当前节点的子菜单
    if ($childUl.length > 0) { // 只有存在子菜单时才触发切换
        $childUl.toggle(); // 切换子菜单显示/隐藏
        $(this).find("img").toggleClass("rotate"); // 箭头旋转切换
    }
});

三、关键技术点解析

1. 递归渲染的核心逻辑

递归的本质是 “自身调用自身”,这里通过pid关联父节点和子节点:

  • 每次调用筛选出当前pid对应的子节点
  • 为每个子节点创建菜单项后,再以该节点的idpid,递归渲染下一级菜单
  • 无子女节点时终止递归,避免死循环

2. 事件委托的应用

由于菜单节点是动态生成的,直接绑定click事件会失效,因此使用$(parent).on("click", "child", function())的委托绑定方式,让父容器监听子节点的点击事件。

      感    谢    大    家    的    观    看  !! !!
      如有补充,欢迎各位大神评论区留言~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值