自定义div模态框打开时如何禁止底层元素滚动仅允许模态框滚动?
实现方案
方案1:JS动态加类(兼容性最好,全场景适用)
第一步:修改CSS样式
首先新增body锁定类,同时给模态框加内部滚动支持,原有代码无需改动:
/* 新增body锁定类 */ .body-lock { overflow: hidden; /* 以下为iOS端适配可选,避免滚动穿透 */ position: fixed; left: 0; width: 100%; /* 避免滚动条消失导致页面横向跳动 */ scrollbar-gutter: stable; } .modalContainer { /* 原有属性保留,新增以下内容 */ overflow-y: auto; /* 移动端优化滚动手感 */ -webkit-overflow-scrolling: touch; }
第二步:添加模态框显隐控制逻辑
切换模态框状态时同步修改body的类,需要保留原页面滚动位置的话补充滚动位置记录逻辑:
const modal = document.getElementById('modal') let recordScrollTop = 0 // 打开模态框 function openModal() { // 记录当前页面滚动位置 recordScrollTop = window.pageYOffset || document.documentElement.scrollTop // 显示模态框 modal.classList.remove('modalHide') modal.classList.add('modalShow') // 锁定底层页面 document.body.classList.add('body-lock') document.body.style.top = `-${recordScrollTop}px` } // 关闭模态框 function closeModal() { // 隐藏模态框 modal.classList.remove('modalShow') modal.classList.add('modalHide') // 解锁底层页面,恢复原滚动位置 document.body.classList.remove('body-lock') window.scrollTo(0, recordScrollTop) }
方案2:纯CSS实现(现代浏览器适用)
如果不需要兼容IE和非常旧的浏览器,可以用CSS :has() 伪类实现,无需额外写JS逻辑:
/* 底层页面自动在模态框显示时锁定 */ body:has(.modalContainer.modalShow) { overflow: hidden; scrollbar-gutter: stable; } .modalContainer { /* 原有属性保留,新增内部滚动支持 */ overflow-y: auto; -webkit-overflow-scrolling: touch; }
边界情况处理
如果遇到模态框滚动到顶部/底部时,继续滑动仍会触发底层页面滚动的iOS特殊情况,可以给模态框添加touchmove事件拦截:
modal.addEventListener('touchmove', (e) => { const scrollTop = modal.scrollTop const scrollHeight = modal.scrollHeight const clientHeight = modal.clientHeight // 滚动到顶部时禁止继续上滑 if (e.targetTouches[0].deltaY > 0 && scrollTop <= 0) { e.preventDefault() } // 滚动到底部时禁止继续下滑 if (e.targetTouches[0].deltaY < 0 && scrollTop + clientHeight >= scrollHeight) { e.preventDefault() } }, { passive: false })
内容的提问来源于stack exchange,提问作者yavgz
相关产品推荐
相关产品推荐

