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

Nuxt集成Hammerjs2.0.8无法检测swipe滑动动作的问题求解

Nuxt 项目 Hammer.js 2.0.8 Swipe 事件不触发排查方案

问题现象

  • 项目中集成 Hammer.js 2.0.8 绑定水平方向swipe事件,回调始终无法执行
  • 将识别器替换为水平方向Pan、绑定pan事件后,回调可正常触发

原实现代码如下:

<template>
  <v-app>
    <v-main>
      <v-container id="touch-container" fluid>
        <div class="items">
          ...
        </div>
      </v-container>
    </v-main>
  </v-app>
</template>

<script>
export default {
  mounted () {
    const Hammer = require('hammerjs')
    const touchContainer = document.getElementById('touch-container')
    const hammer = new Hammer.Manager(touchContainer, {
      recognizers: [
        [Hammer.Swipe, { direction: Hammer.DIRECTION_HORIZONTAL }]
      ]
    })

    hammer.on('swipe', this.handleTouchEvents)
  },
  methods: {
    handleTouchEvents (e) {
      alert(e.type)
    }
  }
}
</script>

<style scoped>
#touch-container {
  height: 100%;
  min-width: 100%;
  overflow-x: hidden;
}

#items {
  touch-action: pan-y;
}
</style>

根因定位&修复

1. 修正CSS选择器与touch-action配置

代码里存在两个CSS配置错误:

  • 模板中滑动内容区的class是items,样式里却用了id选择器#items,规则完全没生效
  • touch-action属性需要配置在Hammer实例直接绑定的容器(即#touch-container)上,Hammer初始化时会读取绑定元素的该属性判断手势接管范围,配置在子元素上不生效。水平滑动场景下配置touch-action: pan-y即可,既允许垂直方向原生页面滚动,又会将水平方向手势交给Hammer处理。

2. 补全Swipe识别器的依赖关联

Hammer.js的Swipe识别器默认依赖Pan识别器输出的滑动位移、速度数据判定是否触发,单独注册Swipe识别器时,因为没有前置手势采集逻辑,会导致识别失败。需要在注册识别器时同时注册Pan,并给Swipe声明依赖关系,同时可以根据需求调整触发阈值:

  • threshold:触发事件需要的最小滑动位移,单位px
  • velocity:触发事件需要的最小滑动速度,单位px/ms

3. 补充实例销毁逻辑

组件卸载时需要销毁Hammer实例,避免内存泄漏和重复绑定问题。

修复后完整代码

<template>
  <v-app>
    <v-main>
      <v-container id="touch-container" fluid>
        <div class="items">
          ...
        </div>
      </v-container>
    </v-main>
  </v-app>
</template>

<script>
export default {
  mounted () {
    const Hammer = require('hammerjs')
    const touchContainer = document.getElementById('touch-container')
    this.hammer = new Hammer.Manager(touchContainer, {
      recognizers: [
        [Hammer.Pan, { direction: Hammer.DIRECTION_HORIZONTAL }],
        [Hammer.Swipe, { 
          direction: Hammer.DIRECTION_HORIZONTAL,
          threshold: 10,
          velocity: 0.3
        }, ['pan']]
      ]
    })

    this.hammer.on('swipe', this.handleTouchEvents)
  },
  beforeDestroy () {
    if (this.hammer) {
      this.hammer.destroy()
    }
  },
  methods: {
    handleTouchEvents (e) {
      alert(e.type)
    }
  }
}
</script>

<style scoped>
#touch-container {
  height: 100%;
  min-width: 100%;
  overflow-x: hidden;
  touch-action: pan-y;
}

.items {
  /* 原有items样式保留即可 */
}
</style>

验证注意事项

  • Swipe是快滑事件,只有滑动速度、位移同时达到阈值才会触发,慢滑默认只会触发pan事件
  • 确认绑定容器没有设置pointer-events: none这类会拦截触摸事件的CSS属性
  • 现有在mounted钩子中引入Hammer的写法符合Nuxt客户端执行要求,不需要额外做SSR兼容处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:54:14