移动端打开固定导航菜单时如何保留页面滚动位置?
如何在固定导航菜单展开时阻止页面滚动且保留滚动位置?
我完全懂你的痛点——用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
相关产品推荐
相关产品推荐

