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

使用Vanilla JS保存CSS手风琴菜单状态(无jQuery)

Preserve Accordion Menu State with Vanilla JavaScript

Hey there! Great question—you absolutely can save your accordion menu's expanded state across page reloads using vanilla JS and the browser's localStorage API. Your current setup uses the :target pseudo-class, which resets when the page reloads because the URL fragment doesn't persist (or changes) when navigating away. Let's fix that with a few simple tweaks.

Step 1: Update Your CSS

First, we'll add a custom class (expanded) to handle the expanded state alongside your existing :target functionality. This lets JS control the state while keeping your current click behavior intact:

.nav_bar { font-family: sans-serif; font-size: 20px; width: 250px; height: 100vh; position: fixed; top: 0px; left: 0px; }
.nav_bar .nav_header { text-align: center; margin: 0; padding: 0; }
.nav_bar .nav_header .nav_logo { width: 180px; }
.nav_bar .menu { margin: 20px; overflow: hidden; }
.nav_bar .menu .item { display: block; margin: 20px; position: relative; }
.nav_bar .menu .item .sub_menu { overflow: hidden; -webkit-transition: 0.3s; transition: 0.3s; max-height: 0; }
.nav_bar .menu .item .sub_menu a::before { content: ''; width: 2px; background: #280F98; position: absolute; top: 0; left: 0; height: 100%; }
.nav_bar .menu .item .sub_menu a { display: block; font-size: 14px; padding: 10px 5px 10px 10px; position: relative; }
/* Add this line to support both :target and JS-controlled expanded state */
.nav_bar .menu .item:target .sub_menu, .nav_bar .menu .item.expanded .sub_menu { max-height: 10em; }

Step 2: Add the Vanilla JavaScript

This code will:

  • Save the expanded menu item's ID to localStorage when it's opened
  • Load the saved state when the page reloads
  • Handle submenu clicks to preserve the parent menu state before navigation

Add this script right before your closing </body> tag:

document.addEventListener('DOMContentLoaded', function() {
  const menuItems = document.querySelectorAll('.nav_bar .menu .item');
  const menuButtons = document.querySelectorAll('.nav_bar .menu .item .button');
  const subMenuLinks = document.querySelectorAll('.nav_bar .menu .item .sub_menu a');

  // Load saved state on page load
  const savedExpandedId = localStorage.getItem('expandedMenuId');
  if (savedExpandedId) {
    const savedItem = document.getElementById(savedExpandedId);
    if (savedItem) {
      savedItem.classList.add('expanded');
    }
  }

  // Handle menu button clicks (toggle expand/collapse)
  menuButtons.forEach(button => {
    button.addEventListener('click', function(e) {
      const parentItem = this.closest('.item');
      const isExpanded = parentItem.classList.contains('expanded');

      // Collapse all other items
      menuItems.forEach(item => {
        if (item !== parentItem) {
          item.classList.remove('expanded');
        }
      });

      // Toggle current item
      if (isExpanded) {
        parentItem.classList.remove('expanded');
        localStorage.removeItem('expandedMenuId');
      } else {
        parentItem.classList.add('expanded');
        localStorage.setItem('expandedMenuId', parentItem.id);
      }
    });
  });

  // Handle submenu link clicks (save state before navigation)
  subMenuLinks.forEach(link => {
    link.addEventListener('click', function() {
      const parentItem = this.closest('.item');
      localStorage.setItem('expandedMenuId', parentItem.id);
    });
  });
});

Step 3: How It Works

  • LocalStorage: This browser feature lets us store small amounts of data (like the expanded menu ID) that persists even after the page is closed or reloaded.
  • DOMContentLoaded: Ensures our JS runs only after the page's HTML is fully loaded.
  • Menu Button Clicks: When you click a menu header, we toggle the expanded class and update localStorage to reflect the current state. We also collapse any other open menus to keep the accordion behavior intact.
  • Submenu Links: When you click a submenu link, we save the parent menu's ID to localStorage right before the page navigates away. When the new page loads, the script reads this ID and expands the correct menu.

Updated HTML (No Changes Needed!)

Your existing HTML works perfectly with this setup—no modifications required here:

<nav class="nav_bar">
  <div class="menu">
    <div class="item" id="our_work">
      <a href="#our_work" class="button">Our Work</a>
      <div class="sub_menu">
        <a href="our_work">Our mission</a>
        <a href="our_work#goals">Goals</a>
        <a href="our_work#initiatives">Initiatives</a>
      </div>
    </div>
    <div class="item" id="performances">
      <a href="#performances" class="button">Showcase</a>
      <div class="sub_menu">
        <a href="#">2020</a>
        <a href="#">2019</a>
        <a href="#">2018</a>
        <a href="#">2017</a>
      </div>
    </div>
    <div class="item" id="concerts">
      <a href="#concerts" class="button">Talent</a>
      <div class="sub_menu">
        <a href="#">Concerts 1</a>
        <a href="#">Concerts 2</a>
        <a href="#">Concerts 3</a>
      </div>
    </div>
    <div class="item" id="shop">
      <a href="#shop" class="button">Shop</a>
      <div class="sub_menu">
        <a href="#">Shop 1</a>
        <a href="#">Shop 2</a>
        <a href="#">Shop 3</a>
      </div>
    </div>
  </div>
</nav>

This setup will keep your accordion menu expanded to the correct section every time the page reloads, whether you clicked the menu header or a submenu link.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:47:33