Metismenu页面跳转后保持菜单展开与高亮状态的技术问询
下面是简单易懂的HTML和JavaScript示例,用sessionStorage保存菜单状态,实现页面跳转/刷新后保持展开层级和高亮项,同时修复aria-expanded设置后菜单不展开的问题:
HTML 代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Metismenu 状态保持</title> <!-- 引入Metismenu样式 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/metismenujs/dist/metismenujs.min.css"> <!-- 引入jQuery(适配jQuery版本Metismenu) --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- 引入Metismenu核心脚本 --> <script src="https://cdn.jsdelivr.net/npm/metismenujs/dist/metismenujs.min.js"></script> </head> <body> <div class="metismenu" id="main-menu"> <ul> <!-- 父菜单1:添加data-menu-id用于标识 --> <li data-menu-id="menu-group-1"> <a href="#" aria-expanded="false">菜单组1</a> <ul> <li><a href="page1.html">页面1</a></li> <li><a href="page2.html">页面2</a></li> </ul> </li> <!-- 父菜单2 --> <li data-menu-id="menu-group-2"> <a href="#" aria-expanded="false">菜单组2</a> <ul> <li><a href="page3.html">页面3</a></li> <li><a href="page4.html">页面4</a></li> </ul> </li> </ul> </div> <script> $(document).ready(function() { // 初始化Metismenu $('#main-menu').metisMenu(); // 页面加载时恢复菜单状态 restoreMenuState(); // 监听父菜单的展开/折叠操作 $('#main-menu [data-menu-id] > a').on('click', function(e) { e.preventDefault(); const menuId = $(this).parent().data('menu-id'); const isExpanded = $(this).attr('aria-expanded') === 'true'; // 更新sessionStorage中的展开状态 if (isExpanded) { sessionStorage.removeItem('expanded-menu'); } else { sessionStorage.setItem('expanded-menu', menuId); } // 触发Metismenu的切换动作 $(this).parent().metisMenu('toggle'); }); // 监听菜单项点击,保存当前页面URL $('#main-menu ul li a').not('[href="#"]').on('click', function() { sessionStorage.setItem('current-page', $(this).attr('href')); }); }); // 恢复菜单状态的核心函数 function restoreMenuState() { const expandedMenuId = sessionStorage.getItem('expanded-menu'); const currentPage = sessionStorage.getItem('current-page'); // 恢复菜单展开状态 if (expandedMenuId) { const targetMenu = $('#main-menu [data-menu-id="' + expandedMenuId + '"]'); // 同时设置aria-expanded属性和Metismenu的展开类 targetMenu.find('> a').attr('aria-expanded', 'true'); targetMenu.addClass('mm-active').find('> ul').addClass('mm-show'); // 重新初始化Metismenu,让它识别已修改的状态 $('#main-menu').metisMenu('dispose').metisMenu(); } // 恢复当前页面的菜单项高亮 if (currentPage) { $('#main-menu ul li a').each(function() { if ($(this).attr('href') === currentPage) { $(this).addClass('mm-active'); // 自动展开当前项的父菜单(如果未展开) const parentMenu = $(this).closest('[data-menu-id]'); parentMenu.addClass('mm-active').find('> a').attr('aria-expanded', 'true').end().find('> ul').addClass('mm-show'); // 重新初始化Metismenu $('#main-menu').metisMenu('dispose').metisMenu(); } }); } } </script> </body> </html>
关键说明
- 状态存储方式:用
sessionStorage保存菜单状态,不会暴露在URL中,关闭浏览器后自动清空,符合常规使用场景。 - 修复aria-expanded不生效:Metismenu的菜单展开需要同时满足三个条件:
aria-expanded="true"、父菜单添加mm-active类、子菜单添加mm-show类,之后必须重新初始化Metismenu才能让它识别状态变化。 - 自动高亮与展开:页面加载时,会根据保存的当前页面URL自动高亮对应菜单项,并展开它的父菜单。
- 兼容性:示例使用jQuery版本的Metismenu,如果你用的是原生JS版本,只需要把jQuery语法改成原生DOM操作即可(比如
document.querySelector替代$)。
内容的提问来源于stack exchange,提问作者Balael
相关产品推荐
相关产品推荐

