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

移动端锚点菜单开合时页面跳顶问题及代码求助

Fixing Mobile Menu Jump-to-Top Issue

Hey there, let's tackle this menu jump issue together—this is a super common gotcha with fixed sidebars and inline event handlers, so let's break down what's happening and fix it step by step.

What's Causing the Jump?

From your code, a few key things are likely triggering the unwanted scroll-to-top behavior:

  • Inline onclick handlers can have inconsistent behavior with return false—even if you add it, the browser might still trigger unintended default actions.
  • Your fixed-position sidenav's width transition forces the browser to recalculate the viewport, which sometimes resets the scroll position automatically.
  • The javascript:void(0) href on your close button isn't as reliable as proper event handling for preventing anchor-related scrolls.

Step-by-Step Fixes

1. Replace Inline Onclicks with Reliable Event Listeners

Inline event handlers are tricky for preventing defaults—let's refactor your code to use proper event listeners, and add scroll position saving/restoring to lock the user's place.

First, update your HTML to remove inline onclick attributes:

<nav>
  <ul id="mySidenav" class="sidenav">
    <a href="#" class="closebtn">&times;</a> <!-- Swap void(0) for #, we'll prevent default later -->
    <li><a class="nav-link" href="#home">Home</a></li>
    <li><a class="nav-link" href="#projects">Projects</a></li>
    <li><a class="nav-link" href="#blog">Blog</a></li>
    <li><a class="nav-link" href="#bio">About the Developer</a></li>
    <li><a class="nav-link" href="#contact">Contact</a></li>
  </ul>
</nav>
<div class="home" id="main">
  <span style="font-size:30px;cursor:pointer" class="menu-toggle"><i class="fas fa-bars"></i></span>
  <h1>This is the content.</h1>
  <section id="home">
    <!-- Your section content -->
  </section>
  <!-- Rest of your sections -->
</div>

Then update your JavaScript to handle events properly and preserve scroll position:

// Grab elements we need
const sidenav = document.getElementById("mySidenav");
const mainContent = document.getElementById("main");
const menuToggle = document.querySelector(".menu-toggle");
const closeBtn = document.querySelector(".closebtn");

// Store scroll position when menu opens
let userScrollPosition = 0;

function openNav() {
  // Save where the user was scrolling
  userScrollPosition = window.scrollY;
  // Lock body to prevent background scrolling while menu is open
  document.body.style.overflow = "hidden";
  // Open the menu
  sidenav.style.width = "250px";
  mainContent.style.marginLeft = "250px";
}

function closeNav(e) {
  // Stop the anchor tag from triggering a scroll
  e.preventDefault();
  // Unlock body scroll
  document.body.style.overflow = "";
  // Close the menu
  sidenav.style.width = "0";
  mainContent.style.marginLeft = "0";
  // Wait for the menu transition to finish, then restore scroll position
  setTimeout(() => {
    window.scrollTo(0, userScrollPosition);
  }, 500); // Matches your 0.5s transition time
}

// Attach event listeners
menuToggle.addEventListener("click", openNav);
closeBtn.addEventListener("click", closeNav);

// Keep your existing scroll-active link logic (fixed a selector issue!)
let mainNavLinks = document.querySelectorAll("nav ul li a");
let mainSections = document.querySelectorAll("#main section"); // Your sections are in #main, not a <main> tag
let lastId;
let cur = [];

window.addEventListener("scroll", event => {
  let fromTop = window.scrollY;
  mainNavLinks.forEach(link => {
    let section = document.querySelector(link.hash);
    if (section) { // Add safety check to avoid errors
      if (section.offsetTop <= fromTop && section.offsetTop + section.offsetHeight > fromTop) {
        link.classList.add("current");
      } else {
        link.classList.remove("current");
      }
    }
  });
});

2. Tweak CSS to Avoid Scroll Shifts

Add these lines to your mobile media query to smooth out transitions and prevent unexpected jumps:

@media only screen and (max-width: 768px) {
  /* Your existing CSS */
  body {
    display: block;
    overflow-x: hidden; /* Prevent horizontal scroll jumps */
  }
  .sidenav, #main {
    transition: all 0.5s ease-in-out; /* Ensure smooth, consistent transitions */
  }
}

Why This Works

  • Saving and restoring the scroll position ensures the user stays exactly where they were before opening the menu.
  • Locking body overflow while the menu is open prevents background scrolling and eliminates one source of scroll shifts.
  • Using addEventListener and preventDefault() reliably stops the close button's anchor tag from triggering a scroll to the top.

Give this a try—it should fix the jump-to-top issue you're facing!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:47:56