You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue滑动卡片应用中interact.js禁用移动端Y轴原生滚动的解决方法

问题根因

interact.js 初始化拖拽实例时,默认会将绑定元素的 CSS touch-action 属性设为none,同时对触摸事件默认执行preventDefault()拦截原生响应,且默认配置不会自动区分用户滑动方向,直接锁死Y轴事件传递,导致移动端页面无法正常纵向滚动。

可行解决方案

方案1:方向判断+自动放行默认事件(推荐,适配全场景)

初始化interact拖拽实例时添加如下配置,仅当判定用户是横向滑动卡片时才触发拖拽逻辑,纵向滑动直接放行给浏览器原生滚动处理:

// 卡片拖拽初始化代码
interact('.swipe-card')
  .draggable({
    inertia: true,
    preventDefault: 'auto', // 核心配置:自动放行非拖拽方向的默认事件
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent',
        endOnly: true
      })
    ],
    listeners: {
      move(event) {
        // 对比横纵向滑动偏移量,判定滑动方向
        const isHorizontalSwipe = Math.abs(event.dx) > Math.abs(event.dy)
        if (!isHorizontalSwipe) {
          // 纵向滑动直接返回,不执行拖拽逻辑,不拦截原生滚动
          return
        }
        // 原有卡片横向滑动逻辑
        const cardEl = event.target
        const offsetX = (parseFloat(cardEl.getAttribute('data-x')) || 0) + event.dx
        cardEl.style.transform = `translateX(${offsetX}px)`
        cardEl.setAttribute('data-x', offsetX)
      },
      end(event) {
        // 原有卡片滑出、回弹逻辑
      }
    }
  })

注意:preventDefault: 'auto'是interact.js官方提供的原生配置项,不会和其他手势逻辑冲突,兼容iOS、安卓全量主流移动端浏览器。

方案2:显式声明触摸动作规则(配置最简单)

直接通过interact提供的touchAction方法,显式告诉浏览器该元素区域内的纵向滑动手势交给原生滚动处理,仅拦截横向手势用于卡片拖拽:

interact('.swipe-card')
  .draggable({
    // 原有拖拽配置
  })
  .touchAction('pan-y') // 核心配置:允许纵向原生滚动

该方案代码量最少,适合不需要做复杂方向判断的简单滑动卡片场景,注意不要手动给元素加touch-action: none的CSS属性,否则会覆盖该配置导致失效。

方案3:Vue项目生命周期适配(框架专属优化)

在Vue项目中,配合组件生命周期动态绑定、销毁interact实例,同时设置拖拽启动阈值,避免误触拦截滚动:

<script setup>
import { onMounted, onUnmounted, ref } from 'vue'
import interact from 'interactjs'

let cardInteract = null
const cardList = ref([])

onMounted(() => {
  cardInteract = interact('.swipe-card')
    .draggable({
      startThreshold: 8, // 滑动偏移超过8px才判定为拖拽,避免点击、轻微滑动误触发拦截
      preventDefault: 'auto',
      listeners: {
        // 拖拽逻辑同方案1
      }
    })
    .touchAction('pan-y')
})

onUnmounted(() => {
  // 组件销毁时解绑interact实例,避免内存泄漏和全局事件污染
  if (cardInteract) cardInteract.unset()
})
</script>
常见避坑点
  • 不要在拖拽move回调里无脑调用event.preventDefault(),会无差别拦截所有原生事件,包括纵向滚动、点击跳转等
  • 1.3.0以下版本的interact.js对preventDefault: 'auto'配置存在兼容性bug,升级到1.10.x及以上稳定版即可正常使用
  • 如果卡片区域内部存在滚动容器,可以给内部滚动容器单独设置touch-action: pan-y,避免事件冒泡被interact拦截

内容的提问来源于stack exchange,提问作者ostaladafab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 23:51:24