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:触发事件需要的最小滑动位移,单位pxvelocity:触发事件需要的最小滑动速度,单位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
相关产品推荐
相关产品推荐

