移动端操作moving-images滑块时禁止页面滚动的实现方法
解决iOS上滑动图片滑块时Body滚动的问题
这个问题在iOS上确实挺常见的,主要是Safari的触摸事件机制导致的——当你在滑块上做垂直方向滑动时,事件会冒泡到body,触发页面的上下滚动。下面给你几个靠谱的解决方案,按推荐程度排序:
方案1:使用CSS overscroll-behavior 属性(最简单)
这是现代浏览器支持的原生属性,可以直接限制滚动行为的溢出范围。给你的滑块容器加上这个样式就行:
.moving-images { overscroll-behavior: contain; }
它会把滑块内部的滚动(如果有的话)完全限制在容器内,不会触发外部body的滚动。不过要注意,iOS Safari 13.4及以上版本才支持这个属性,如果你的项目需要兼容更早的系统,就得用下面的方案。
方案2:JavaScript监听触摸事件,精准阻止默认行为
针对低版本iOS,我们可以通过监听触摸事件,判断滑动方向,只在垂直滑动时阻止默认行为,同时保留滑块的水平滑动功能:
const slider = document.querySelector('.moving-images'); let startY; // 记录触摸起始的Y坐标 slider.addEventListener('touchstart', (e) => { startY = e.touches[0].clientY; }, { passive: true }); // 处理滑动事件 slider.addEventListener('touchmove', (e) => { const currentY = e.touches[0].clientY; const diffY = Math.abs(currentY - startY); // 当垂直滑动距离超过小阈值时,阻止默认行为(避免页面滚动) // 如果你需要滑块支持垂直滚动,就反过来判断水平滑动距离 if (diffY > 5) { e.preventDefault(); } }, { passive: false }); // 必须设置passive:false,不然iOS上preventDefault会失效
这个方案的优势是精准,不会影响滑块本身的交互,但需要根据你滑块的实际滑动方向调整判断逻辑。
方案3:临时禁用Body滚动(滑块交互时)
如果上面的方案都不适用,还可以在滑块被触摸时,临时给body添加禁止滚动的样式,交互结束后再恢复:
先写CSS样式:
.body-no-scroll { position: fixed; width: 100%; height: 100%; overflow: hidden; }
再写JavaScript逻辑(解决页面跳回顶部的问题):
const slider = document.querySelector('.moving-images'); const body = document.body; let scrollTop = 0; // 触摸开始时禁用滚动,记录当前滚动位置 slider.addEventListener('touchstart', () => { scrollTop = window.scrollY; body.classList.add('body-no-scroll'); body.style.top = `-${scrollTop}px`; }); // 触摸结束/取消时恢复滚动 function restoreScroll() { body.classList.remove('body-no-scroll'); window.scrollTo(0, scrollTop); body.style.top = ''; } slider.addEventListener('touchend', restoreScroll); slider.addEventListener('touchcancel', restoreScroll);
这个方案逻辑稍复杂,但兼容性最好,适合所有iOS版本。
额外提示
iOS Safari默认会给touchmove事件设置passive: true,这会导致e.preventDefault()失效,所以方案2里一定要显式设置passive: false,这点很关键!
总结一下,优先用方案1,不行再试方案2,最后考虑方案3,根据你的项目兼容需求和滑块交互逻辑选最合适的就行~
内容的提问来源于stack exchange,提问作者Jacklyn N
相关产品推荐
相关产品推荐

