移动端触摸场景下如何避免拖动range slider时触发页面整体拖拽?
移动端range slider拖拽避免触发页面整体滚动的可行方案
CSS属性控制(最简便方案)
给range slider元素添加CSS的touch-action属性即可:- 若slider为横向拖动,添加
touch-action: pan-y:仅允许页面纵向滚动,横向触摸操作不会触发浏览器默认的页面平移行为,完全交由slider组件处理拖拽逻辑 - 若slider为纵向拖动,添加
touch-action: pan-x:仅允许页面横向滚动 - 若需要完全禁用该区域的所有默认触摸行为,添加
touch-action: none
该属性目前移动端全平台支持度超过97%,无需额外JS逻辑即可解决问题。
- 若slider为横向拖动,添加
触摸事件精准拦截
给slider绑定触摸事件,仅在拖拽状态下阻止事件默认行为,避免影响页面其他功能:// 以原生JS为例 let isDragging = false const slider = document.querySelector('.range-slider') slider.addEventListener('touchstart', (e) => { isDragging = true e.stopPropagation() }) slider.addEventListener('touchmove', (e) => { if (isDragging) { e.preventDefault() e.stopPropagation() // 此处加入slider的拖拽位置更新逻辑 } }) slider.addEventListener('touchend touchcancel', () => { isDragging = false })注意不要全局阻止
touchmove事件,仅在slider拖拽状态下拦截即可,避免影响页面正常滚动、点击等交互。拖拽时动态禁用页面滚动
在slider拖拽开始时,给页面根元素/body添加禁用滚动的样式,拖拽结束后移除:.page-no-scroll { overflow: hidden; height: 100vh; position: fixed; width: 100%; }该方案适合需要完全锁定页面滚动的场景,缺点是会丢失当前的滚动位置,可在加样式前记录当前
scrollTop,移除样式后再复位滚动位置解决该问题。组件内置配置开启
若使用第三方的slider组件库,大部分都已封装了滚动冲突的处理逻辑,直接开启对应配置项即可,比如常用的React/Vue slider组件一般都提供preventScroll、lockScroll这类属性,开启后自动处理冲突。
内容的提问来源于stack exchange,提问作者Александр Сорокин
相关产品推荐
相关产品推荐

