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

页面刷新后如何保存嵌套菜单的切换状态?

问题:侧边栏菜单状态刷新后重置,如何用localStorage保存?

我刚开始学习JavaScript,若问题较为浅显还请见谅。
我有一个侧边栏菜单,其中包含多层默认隐藏的子菜单项,可切换显示或隐藏。当前功能正常,但页面刷新后菜单状态会重置。
是否有相对简单的方法,利用localStorage保存状态,使其在页面刷新后保持不变?具体实现方式是怎样的?

现有代码:

JavaScript:

const todos = document.querySelectorAll(".todo");
const togglers = document.querySelectorAll(".toggler");

todos.forEach((todo) => {
  todo.addEventListener("click", () => {
    todo.classList.toggle("active");
  });
});

togglers.forEach((toggler) => {
  toggler.addEventListener("click", () => {
    toggler.classList.toggle("active");
    toggler.nextElementSibling.classList.toggle("active");
  });
});

HTML(部分):

<div class="sidebar">
  <ul class="todos" id="todos">
    <div class="toggler">Resolve Exterior Herbs</div>
    <ul class="toggler-target">
      <li class="todo">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#">Introduction</a></li>                  
      <div class="toggler">Dispel Wind Cold Herbs</div> 
      <ul class="toggler-target">
        <li class="todo">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#">Introduction</a></li>               

解决方案

核心思路是给每个可切换元素设置唯一标识,切换状态时将状态存入localStorage,页面加载时再从localStorage读取并恢复状态。

步骤1:给元素添加唯一ID

先给每个toggler和todo设置唯一id,确保状态能精准对应:

<div class="sidebar">
  <ul class="todos" id="todos">
    <div class="toggler" id="toggler-1">Resolve Exterior Herbs</div>
    <ul class="toggler-target">
      <li class="todo" id="todo-1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#">Introduction</a></li>                  
      <div class="toggler" id="toggler-2">Dispel Wind Cold Herbs</div> 
      <ul class="toggler-target">
        <li class="todo" id="todo-2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#">Introduction</a></li>               

步骤2:修改JavaScript代码实现状态管理

// 从localStorage加载保存的状态
function loadState() {
  // 恢复toggler的展开/收起状态
  document.querySelectorAll(".toggler").forEach(toggler => {
    const savedState = localStorage.getItem(`toggler-${toggler.id}`);
    if (savedState === "active") {
      toggler.classList.add("active");
      toggler.nextElementSibling.classList.add("active");
    }
  });

  // 恢复todo的选中状态
  document.querySelectorAll(".todo").forEach(todo => {
    const savedState = localStorage.getItem(`todo-${todo.id}`);
    if (savedState === "active") {
      todo.classList.add("active");
    }
  });
}

// 保存单个元素的状态到localStorage
function saveElementState(element, prefix) {
  const isActive = element.classList.contains("active");
  localStorage.setItem(`${prefix}-${element.id}`, isActive ? "active" : "inactive");
}

// 初始化事件监听
function initEventListeners() {
  // todo的点击事件
  document.querySelectorAll(".todo").forEach(todo => {
    todo.addEventListener("click", () => {
      todo.classList.toggle("active");
      saveElementState(todo, "todo");
    });
  });

  // toggler的点击事件
  document.querySelectorAll(".toggler").forEach(toggler => {
    toggler.addEventListener("click", () => {
      toggler.classList.toggle("active");
      toggler.nextElementSibling.classList.toggle("active");
      saveElementState(toggler, "toggler");
    });
  });
}

// 页面DOM加载完成后,先恢复状态再绑定事件
window.addEventListener("DOMContentLoaded", () => {
  loadState();
  initEventListeners();
});

代码说明:

  • loadState:页面加载时,遍历所有可切换元素,从localStorage读取之前保存的状态,对应添加active类。
  • saveElementState:通用状态保存函数,用「前缀+元素ID」作为存储键名,避免不同类型元素的状态冲突。
  • initEventListeners:在原有点击逻辑基础上,增加状态保存的调用,确保每次切换都同步更新localStorage。
  • DOMContentLoaded事件:确保DOM完全加载后再执行状态恢复和事件绑定,避免找不到元素的问题。

注意事项:

  • 务必保证每个元素的ID唯一,否则会出现状态覆盖的问题。
  • localStorage只能存储字符串,所以用"active"和"inactive"标识状态。
  • 若需要清空所有保存的状态,可在控制台执行localStorage.clear();删除单个状态则用localStorage.removeItem("toggler-1")。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:48:22