如何使用CSS和JS禁用父元素触摸并启用子元素触摸,同时禁止父元素滚动
解决方案
一、移动端触摸交互适配修复
部分移动端内核对触摸事件的pointer-events属性支持存在兼容缺陷,可通过以下两种方案修复:
方案1:CSS属性补充(优先使用,改造成本最低)
新增touch-action属性专门控制移动端触摸行为,调整后样式如下:
.parent { pointer-events: none; /* 禁用父元素所有默认触摸行为 */ touch-action: none; } .child { pointer-events: auto; /* 恢复子元素自身触摸权限 */ touch-action: auto; }
方案2:JS事件拦截兜底(兼容极低版本移动端环境)
如果CSS方案仍存在兼容问题,可通过事件拦截实现需求,注意事件监听的passive参数必须设为false,否则移动端preventDefault会失效:
const parent = document.querySelector('.parent') const child = document.querySelector('.child') const preventParentTouch = (e) => { // 事件源不属于子元素内部时,拦截触摸事件 if (!child.contains(e.target)) { e.preventDefault() e.stopPropagation() } } // 模态框打开时绑定事件 parent.addEventListener('touchstart', preventParentTouch, { passive: false }) parent.addEventListener('touchmove', preventParentTouch, { passive: false }) parent.addEventListener('touchend', preventParentTouch, { passive: false }) // 模态框关闭时移除事件,避免影响正常交互 // parent.removeEventListener('touchstart', preventParentTouch) // parent.removeEventListener('touchmove', preventParentTouch) // parent.removeEventListener('touchend', preventParentTouch)
二、父元素禁止滚动实现
根据需求场景选择对应方案:
场景1:禁止整个页面滚动
为避免添加overflow: hidden后页面自动跳回顶部,需要记录并还原滚动位置:
/* 全局滚动禁用类 */ .modal-open { overflow: hidden; position: fixed; left: 0; right: 0; width: 100%; }
let recordScrollTop = 0 // 打开模态框时执行 const openModal = () => { recordScrollTop = window.pageYOffset || document.documentElement.scrollTop document.documentElement.classList.add('modal-open') document.body.classList.add('modal-open') document.body.style.top = `-${recordScrollTop}px` } // 关闭模态框时执行 const closeModal = () => { document.documentElement.classList.remove('modal-open') document.body.classList.remove('modal-open') window.scrollTo(0, recordScrollTop) }
场景2:仅禁止.parent容器滚动
直接在模态框打开时给父元素添加overflow: hidden样式,关闭时移除即可,无需额外处理。
内容的提问来源于stack exchange,提问作者anoop francis
相关产品推荐
相关产品推荐

