页面刷新时保持下拉菜单展开:JS中sessionStorage返回null问题
问题分析与解决方案
你的代码核心问题是循环变量的闭包引用错误,导致sessionStorage存储的键值和实际需求不匹配,同时循环变量未用块级声明引发全局污染,具体问题点:
- 循环里的
i未用let声明,会成为全局变量,循环结束后i的值等于nome_menu.length(也就是2)。点击事件触发时,箭头函数捕获的是i的最终值,所以存储的键是menu2,但初始化时你尝试获取的是menu0和menu1,自然返回null。 - 即使修复变量声明,若不用
let在循环内声明i,箭头函数仍会捕获循环变量的引用,依然出现键值不匹配的问题。
修正后的代码
let nome_menu = ['menu-situacao', 'menu-pronome']; // 用let声明循环变量i,确保每个迭代的i是独立的块级变量 for(let i = 0; i < nome_menu.length; i++){ let menu = document.querySelector('.'+nome_menu[i]); let sub_menu = document.querySelector('.'+nome_menu[i].replace("menu-", "ul-")); // 从sessionStorage获取初始状态,默认0(收起) let j = parseInt(sessionStorage.getItem('menu'+i)) || 0; // 直接根据初始状态设置菜单显示,无需模拟click sub_menu.style.display = j === 1 ? 'block' : 'none'; menu.addEventListener('click', () =>{ if(j === 0){ sub_menu.style.display = 'block'; j = 1; }else{ sub_menu.style.display = 'none'; j = 0; } // 存储当前状态到sessionStorage sessionStorage.setItem('menu'+i, j); }) }
额外优化建议
- 避免用
menu.click()初始化菜单状态,直接设置style.display更高效,还不会触发额外的点击事件逻辑。 - 用
parseInt解析sessionStorage的值,因为sessionStorage存储的都是字符串,使用严格相等判断时需要统一类型。 - 建议用CSS类控制菜单显示隐藏,比如定义
.sub-menu-hidden { display: none; },再通过sub_menu.classList.toggle('sub-menu-hidden')切换,比直接操作style.display更符合前端工程化实践。
内容的提问来源于stack exchange,提问作者Marckson Assis
相关产品推荐
相关产品推荐

