如何在弹出菜单激活时禁止页面滚动,关闭时恢复滚动?
解决弹窗菜单激活时禁止背景滚动的问题
我正在制作一个弹窗菜单,点击按钮可显示/隐藏菜单内容,需求是菜单激活时禁止页面背景滚动,关闭菜单后恢复滚动。目前已实现菜单的显示/隐藏功能,但直接给body设置overflow:hidden会导致关闭菜单后页面无法正常滚动,网站为多页面结构。
现有代码示例
HTML
<div class="first"> <div class="menubtn"> menubtn </div> <div class="menu"> menu items </div> </div> <div class="second"> second </div>
CSS
.first,.second{ height:100vh; font-size:50px; display:grid; place-content:center; } .menu{ position:absolute; display:none; } .menu.active{ display:flex; }
JavaScript
const menubtn = document.getElementsByClassName("menubtn")[0]; const menuopen = document.getElementsByClassName("menu")[0]; menubtn.addEventListener("click", () => { menuopen.classList.toggle("active"); });
解决方案
核心思路是记录当前滚动位置,避免直接设置overflow:hidden导致的滚动位置丢失,同时通过类来控制body的滚动状态,而非直接修改样式属性。
- 新增CSS类控制body固定
.body-fixed { position: fixed; width: 100%; top: var(--scroll-top, 0); }
- 修改JavaScript逻辑处理滚动状态切换
const menubtn = document.querySelector(".menubtn"); const menuopen = document.querySelector(".menu"); menubtn.addEventListener("click", () => { const isMenuActive = menuopen.classList.toggle("active"); if (isMenuActive) { // 记录当前滚动位置 const scrollPosition = window.pageYOffset || document.documentElement.scrollTop; // 通过CSS变量保存滚动位置,固定body document.body.style.setProperty("--scroll-top", `-${scrollPosition}px`); document.body.classList.add("body-fixed"); } else { // 读取保存的滚动位置 const scrollPosition = -parseInt(document.body.style.getPropertyValue("--scroll-top")); // 移除固定类,恢复滚动 document.body.classList.remove("body-fixed"); // 滚动到之前的位置 window.scrollTo(0, scrollPosition); // 清除CSS变量 document.body.style.removeProperty("--scroll-top"); } });
- 方案优势
- 避免了
overflow:hidden导致的页面跳顶问题,恢复菜单时能回到用户之前浏览的位置,体验更好。 - 用类控制状态,逻辑清晰,多页面结构下可以轻松复用该代码。
内容的提问来源于stack exchange,提问作者Prabesh Shrestha
相关产品推荐
相关产品推荐

