移动端sticky粘性头部菜单滚动失效,如何实现可滚动并保留滚动位置?
粘性头部下拉菜单移动端滚动问题解决方案
核心思路
不用额外存储滚动位置,通过调整菜单的定位和滚动容器属性,配合页面滚动锁定,就能解决问题:
1. 让下拉菜单成为独立滚动容器
下拉菜单不需要继承头部的sticky/fixed定位,而是作为头部的绝对定位子元素,同时限制自身高度并开启纵向滚动:
/* 头部基础样式 - 保持sticky特性 */ .header { position: sticky; top: 0; width: 100%; height: 60px; /* 自定义头部高度,需和下方calc值对应 */ background: #fff; z-index: 999; padding: 0 16px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } /* 下拉菜单样式 */ .dropdown-menu { position: absolute; top: 100%; /* 紧贴头部下方展开 */ left: 0; right: 0; background: #fff; box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* 限制菜单高度为视口高度减去头部高度,避免超出屏幕 */ max-height: calc(100vh - 60px); /* 内容超出时允许纵向滚动 */ overflow-y: auto; /* 默认隐藏菜单 */ display: none; } /* 菜单展开时显示 */ .header.menu-active .dropdown-menu { display: block; }
2. 锁定页面滚动,避免关闭菜单后位置偏移
菜单展开时给body添加类,锁定页面滚动;关闭时移除类,页面自动回到原滚动位置:
/* 页面滚动锁定样式 */ body.menu-active { overflow: hidden; position: fixed; width: 100%; }
3. 简单JS切换逻辑
const menuBtn = document.querySelector('.menu-btn'); const header = document.querySelector('.header'); const body = document.body; menuBtn.addEventListener('click', () => { header.classList.toggle('menu-active'); body.classList.toggle('menu-active'); });
方案说明
- 菜单用
absolute定位依附于sticky头部,既保留了头部的粘性特性,又让菜单成为独立的滚动容器,内容过长时可以内部滚动 - 通过
position: fixed锁定body,页面会固定在当前滚动位置,关闭菜单后移除类,浏览器会自动恢复之前的滚动状态,完全不需要手动存储滚动值
内容的提问来源于stack exchange,提问作者user28551593
相关产品推荐
相关产品推荐

