实现侧边栏子菜单联动切换及页面重载状态记忆
侧边栏菜单展开状态同步与重载保持问题
我的侧边栏代码
<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
相关产品推荐
相关产品推荐

