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

移动端打开固定导航菜单时如何保留页面滚动位置?

如何在固定导航菜单展开时阻止页面滚动且保留滚动位置?

我完全懂你的痛点——用position: fixed阻止滚动却导致页面跳回顶部,那种记录滚动位置再恢复的方法确实有点繁琐,而且在某些边缘场景下容易出问题。下面给你两个更优雅的解决方案,既能阻止页面滚动,又能完美保留用户的浏览位置:


方案1:用overflow: hidden替代position: fixed(推荐)

问题的核心是:给body设置position: fixed时,浏览器会重置滚动上下文,直接把页面拉回顶部。我们可以改用overflow: hidden来阻止滚动,同时针对iOS Safari的特性做适配:

修改后的CSS

/* 移除position: fixed,改用overflow:hidden + touch-action禁止触摸滚动 */
.overlay-visible {
  overflow: hidden;
  touch-action: none; /* 阻止iOS的弹性滚动行为 */
}
/* 同时给html也设置overflow:hidden,确保iOS Safari生效 */
html.overlay-visible {
  overflow: hidden;
}

/* 原有样式保持不变 */
header { 
  position: fixed; 
  background-color: white; 
  padding: 20px; 
  display: flex; 
  justify-content: space-between; 
  align-items: center; 
}
.container { padding-top: 80px; }
#menu-icon { font-size: 30px; }
nav { 
  display: none; 
  z-index: 10; 
  position: fixed; 
  top: 80px; 
  left: 0; 
  right: 0; 
  bottom: 0; 
  padding-bottom: 48px; 
  font-size: 15px; 
  overflow-y: scroll; 
  -webkit-overflow-scrolling: touch; 
  background-color: rgba(0, 0, 0, 0.5); 
}
ul { background-color: dodgerblue; }
li { padding: 20px; }
img { width: 100%; }

修改后的JS

$('#menu-icon').on('click', () => { 
  $('nav').toggle();
  // 同时给body和html切换类,确保全平台生效
  $('body, html').toggleClass('overlay-visible');
});

这个方案的优势是纯CSS+极简JS实现,不需要记录滚动位置,完全不会破坏页面的滚动上下文,完美保留用户的浏览位置。


方案2:优化position: fixed的实现(兼容极端场景)

如果你的场景中overflow: hidden无法完全阻止滚动(比如某些老版本iOS),可以用position: fixed但手动设置top值来固定滚动位置,比你之前的hack更可靠:

修改后的JS

let scrollPosition = 0;

$('#menu-icon').on('click', () => { 
  $('nav').toggle();
  const isMenuVisible = $('nav').is(':visible');
  
  if (isMenuVisible) {
    // 记录当前滚动位置
    scrollPosition = window.pageYOffset || document.documentElement.scrollTop;
    // 设置body为fixed,同时top设为负的滚动位置,保持页面不动
    $('body').css({
      'position': 'fixed',
      'top': `-${scrollPosition}px`,
      'width': '100%'
    }).addClass('overlay-visible');
  } else {
    // 移除fixed定位,恢复滚动位置
    $('body').css({
      'position': '',
      'top': ''
    }).removeClass('overlay-visible');
    window.scrollTo(0, scrollPosition);
  }
});

对应的CSS(简化版)

.overlay-visible {
  overflow: hidden;
}

这个方案只在菜单切换时记录一次滚动位置,恢复逻辑精准,能兼容overflow: hidden搞不定的极端场景。


两种方案在iPhone Safari模拟器中都能完美解决页面跳回顶部的问题,同时阻止背景页面滚动,菜单内部的滚动也不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:35:58