模态框打开时禁止body标签滚动的问题求助
解决模态框打开时禁止Body滚动的问题
嘿,我看你在模态框弹出后想锁住Body滚动这件事上碰钉子了,试过wheelscroll函数和CSS方案都没效果对吧?别着急,我给你两个亲测有效的方案,应该能搞定这个问题。
方案一:CSS + JS 组合(推荐)
这个方案是最常用的,通过给Body添加/移除类来控制滚动,同时还能解决滚动条消失导致页面偏移的问题。
第一步:添加CSS样式
先在你的样式表中加入这个类:
/* 禁止Body滚动的类 */ .no-scroll { overflow: hidden; /* 用CSS变量保存滚动条宽度,防止页面偏移 */ padding-right: var(--scrollbar-width, 0); }
第二步:修改JS逻辑
我们需要在模态框打开时给Body加上这个类,关闭时移除,同时计算滚动条宽度来抵消页面偏移:
首先添加一个计算滚动条宽度的小函数:
// 计算浏览器滚动条的宽度 function getScrollbarWidth() { const documentWidth = document.documentElement.clientWidth; const windowWidth = window.innerWidth; return windowWidth - documentWidth; }
然后修改你的popupOpenClose函数,加上控制滚动的逻辑,同时别忘了把你的.close按钮也加入关闭监听(原来的代码只监听了button[name=close],但你的关闭按钮是a标签):
/* eslint-disable */ function popupOpenClose(popup) { /* Open popup */ $(popup).show(); // 打开模态框时:禁止Body滚动 const scrollbarWidth = getScrollbarWidth(); document.body.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`); document.body.classList.add('no-scroll'); /* Close popup if user clicks on background */ $(popup).click(function(e) { if ( e.target == this ) { if ($(popup).is(':visible')) { $(popup).hide(); // 关闭时恢复滚动 document.body.classList.remove('no-scroll'); document.body.style.removeProperty('--scrollbar-width'); } } }); /* Close popup and remove errors if user clicks on cancel or close buttons */ $(popup).find("button[name=close], .close").on("click", function() { if ($(".formElementError").is(':visible')) { $(".formElementError").remove(); } $(popup).hide(); // 关闭时恢复滚动 document.body.classList.remove('no-scroll'); document.body.style.removeProperty('--scrollbar-width'); }); } $(document).ready(function () { $("[data-js=open]").on("click", function() { popupOpenClose($(".popup")); }); // 给你的CENIK按钮绑定打开事件(原按钮无data-js属性) $(".button[href='#popup1']").on("click", function(e) { e.preventDefault(); popupOpenClose("#popup1"); }); })
注:我给你的CENIK按钮也加了打开事件,因为原来的JS只监听了
[data-js=open]元素,但你的按钮没有这个属性,这样点击CENIK就能正确弹出模态框啦。
方案二:JS阻止滚动事件(备选)
如果CSS方案还是无效,可能是你的页面结构里有其他滚动容器,这时候可以直接用JS阻止滚动事件:
/* eslint-disable */ let isModalActive = false; // 阻止滚动的函数 function blockScroll(e) { e.preventDefault(); e.stopPropagation(); } function popupOpenClose(popup) { /* Open popup */ $(popup).show(); isModalActive = true; // 监听滚动事件,注意要设置passive:false,否则preventDefault无效 document.body.addEventListener('wheel', blockScroll, { passive: false }); document.body.addEventListener('touchmove', blockScroll, { passive: false }); // 适配移动端 /* Close popup if user clicks on background */ $(popup).click(function(e) { if ( e.target == this ) { if ($(popup).is(':visible')) { $(popup).hide(); isModalActive = false; // 移除监听,恢复滚动 document.body.removeEventListener('wheel', blockScroll); document.body.removeEventListener('touchmove', blockScroll); } } }); /* Close popup and remove errors if user clicks on cancel or close buttons */ $(popup).find("button[name=close], .close").on("click", function() { if ($(".formElementError").is(':visible')) { $(".formElementError").remove(); } $(popup).hide(); isModalActive = false; // 移除监听,恢复滚动 document.body.removeEventListener('wheel', blockScroll); document.body.removeEventListener('touchmove', blockScroll); }); } $(document).ready(function () { $("[data-js=open]").on("click", function() { popupOpenClose($(".popup")); }); $(".button[href='#popup1']").on("click", function(e) { e.preventDefault(); popupOpenClose("#popup1"); }); })
这个方案的核心是在模态框打开时给Body绑定阻止滚动的事件,关闭时解绑。要注意设置passive: false,因为现代浏览器默认touchmove等事件是passive模式,preventDefault会失效。
内容的提问来源于stack exchange,提问作者msoboc4
相关产品推荐
相关产品推荐

