You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现侧边栏子菜单联动切换及页面重载状态记忆

侧边栏菜单展开状态同步与重载保持问题

我的侧边栏代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-blue-400 sidebar collapse">
        <div class="position-sticky pt-3 sidebar-sticky" style="width: 190px;">

            <ul class="list-unstyled ps-0">
                <li class="border-top my-3"></li>
                @hasrole('admin')

                <li class="mb-1">
                    <button class="btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed"
                            data-bs-toggle="collapse" data-bs-target="#home-collapse" aria-expanded="true">
                        用户管理
                    </button>
                    <div class="collapse show" id="home-collapse">
                        <ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
                            @can('view users')
                                <li><a href="{{ url('admin/users') }}"
                                       class="link-dark d-inline-flex text-decoration-none rounded active">用户列表</a></li>
                            @endcan
                            @can('add users')
                                <li><a href="{{ url('admin/users/create') }}"
                                       class="link-dark d-inline-flex text-decoration-none rounded">新增用户</a></li>
                            @endcan
                            <li><a href="{{ url('admin/roles') }}"
                                   class="link-dark d-inline-flex text-decoration-none rounded">角色管理</a></li>
                        </ul>
                    </div>
                </li>
                <li class="mb-1">
                    <button class="btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed"
                            data-bs-toggle="collapse" data-bs-target="#dashboard-collapse" aria-expanded="false">
                        组织架构
                    </button>
                    <div class="collapse" id="dashboard-collapse">
                        <ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
                            <li><a href="{{ url('admin/faculties') }}"
                                   class="link-dark d-inline-flex text-decoration-none rounded">学院管理</a></li>
                            <li><a href="{{ url('admin/departments') }}"
                                   class="link-dark d-inline-flex text-decoration-none rounded">系部管理</a></li>
                            <li><a href="{{ url('admin/degreePrograms') }}"
                                   class="link-dark d-inline-flex text-decoration-none rounded">学位项目</a></li>
                        </ul>
                    </div>
                </li>
                <li class="mb-1">
                    <button class="btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed"
                            data-bs-toggle="collapse" data-bs-target="#orders-collapse" aria-expanded="false">
                        学期管理
                    </button>
                    <div class="collapse" id="orders-collapse">
                        <ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
                            <li><a href="{{ url('admin/semesters') }}"
                                   class="link-dark d-inline-flex text-decoration-none rounded">学期列表</a></li>
                        </ul>
                    </div>
                </li>
                @endhasrole
                @hasanyrole('Dean|Thesis Coordinator|GRC member|HoD|GRC Convenior')
                <li class="border-top my-3"></li>
                <li class="mb-1">
                    <button class="btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed"
                            data-bs-toggle="collapse" data-bs-target="#academic-users-collapse" aria-expanded="false">
                        学术用户
                    </button>
                    <div class="collapse" id="academic-users-collapse">
                        <ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
                            <li><a href="{{ url('academic_users/users') }}"
                                   class="link-dark d-inline-flex text-decoration-none rounded">用户列表</a>
                            </li>
                        </ul>
                    </div>
                </li>
                @endhasanyrole
                <li class="border-top my-3"></li>
                <li class="mb-1">
                    <button class="btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed"
                            data-bs-toggle="collapse" data-bs-target="#account-collapse" aria-expanded="false">
                        账户设置
                    </button>
                    <div class="collapse" id="account-collapse">
                        <ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small">
                            <li><a href="#" class="link-dark d-inline-flex text-decoration-none rounded">个人资料</a>
                            </li>
                            <li><a href="#" class="link-dark d-inline-flex text-decoration-none rounded">设置</a>
                            </li>
                            <li>
                                <form method="POST" id="logout" action="{{ route('logout') }}" x-data>
                                    @csrf
                                    <a href="#" class="link-dark d-inline-flex text-decoration-none rounded"
                                       onclick="logout()">
                                        <i class='bx bx-log-out nav_icon'></i>
                                        <span class="nav_name">退出登录</span>
                                    </a>
                                </form>
                            </li>
                        </ul>
                    </div>
                </li>
            </ul>
        </div>
    </nav>

侧边栏现状

侧边栏导航

需求

点击「学院管理」这类子菜单链接时,需要实现:

  • 收起「用户管理」子菜单
  • 展开「组织架构」子菜单
  • 上述状态在页面重载后依然保持

当前问题

点击学院管理链接跳转到对应页面后,「用户管理」子菜单仍处于展开状态,其他子菜单都隐藏了。
当前导航栏状态


解决方案

步骤1:给子菜单链接添加父面板标识

给每个子菜单的<a>标签加上data-parent-collapse属性,指定它所属的父折叠面板ID。比如学院管理的链接修改为:

<li><a href="{{ url('admin/faculties') }}"
       class="link-dark d-inline-flex text-decoration-none rounded"
       data-parent-collapse="#dashboard-collapse">学院管理</a></li>

其他子菜单链接同理,比如用户列表对应#home-collapse,角色管理对应#home-collapse,以此类推。

步骤2:编写JS处理状态切换与存储

用jQuery实现点击时自动切换折叠状态,同时把当前展开的面板ID存在浏览器本地存储里,页面重载时自动恢复:

$(document).ready(function() {
    // 页面加载时恢复之前存储的状态
    const activePanel = localStorage.getItem('activeSidebarPanel');
    if (activePanel) {
        // 先收起所有面板
        $('.collapse').removeClass('show');
        $('[aria-expanded="true"]').attr('aria-expanded', 'false');
        // 展开之前存储的面板
        $(activePanel).addClass('show');
        $(`[data-bs-target="${activePanel}"]`).attr('aria-expanded', 'true');
    }

    // 点击子菜单链接时更新状态
    $('.btn-toggle-nav a').click(function() {
        const targetPanel = $(this).data('parent-collapse');
        if (targetPanel) {
            // 收起所有非目标面板
            $('.collapse').not(targetPanel).removeClass('show');
            $('[aria-expanded="true"]').not(`[data-bs-target="${targetPanel}"]`).attr('aria-expanded', 'false');
            // 展开目标面板
            $(targetPanel).addClass('show');
            $(`[data-bs-target="${targetPanel}"]`).attr('aria-expanded', 'true');
            // 把当前面板ID存到本地存储
            localStorage.setItem('activeSidebarPanel', targetPanel);
        }
    });

    // 点击折叠按钮时也同步更新存储
    $('.btn-toggle').click(function() {
        const targetPanel = $(this).data('bs-target');
        // 等Bootstrap动画结束后判断状态
        setTimeout(() => {
            if ($(targetPanel).hasClass('show')) {
                localStorage.setItem('activeSidebarPanel', targetPanel);
            } else {
                localStorage.removeItem('activeSidebarPanel');
            }
        }, 300);
    });
});

注意事项

  • 确保Bootstrap的JS文件已经引入(当前代码仅引入了jQuery,折叠功能依赖Bootstrap JS)
  • 本地存储的状态会在用户清除浏览器缓存时丢失,若需要跨设备保持状态,需改用后端会话存储
  • Laravel Blade生成的动态菜单,要确保data-parent-collapse属性正确对应到父面板的ID

内容的提问来源于stack exchange,提问作者Usman Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 05:45:32