为什么手势滑动动画组件时会出现延迟和冲突?

A. 丽苹 阅读 65

我在用Hammer.js给动画组件添加滑动手势时,发现滑动触发有0.5秒延迟,而且和页面滚动冲突。调整过threshold参数没用,代码是这样的:


const mc = new Hammer(element);
mc.get('pan').set({ threshold: 5, direction: Hammer.DIRECTION_ALL });
mc.on("panstart panmove", (e) => {
  if (e.direction === Hammer.DIRECTION_LEFT) {
    this.translateX += e.deltaX;
    this.updateAnimation();
  }
});

手指快速滑动时组件卡顿,有时候还会触发浏览器原生滚动。试过设置touch-action: none但没生效,求解

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
玉涵 ☘︎
你这个问题挺典型的,主要是因为 Hammer.js 默认行为和浏览器原生滚动之间存在竞争关系,再加上动画更新的性能问题导致的卡顿。先说几个关键点:

1. 延迟问题:Hammer.js 的 pan 事件本身会有一点延迟,尤其是在移动设备上。你可以改用 swipe 事件来试试,或者把 threshold 设得更小一点,比如设成 1。

2. 滚动冲突:你提到加了 touch-action: none 没用,那是因为有些浏览器默认还是会处理滚动。建议你在初始化 Hammer 的时候,通过 touchAction 选项来控制:

const mc = new Hammer(element, null, {
touchAction: 'none'
});


这样可以更有效地阻止浏览器原生滚动。

3. 卡顿问题:你在 panmove 里频繁调用 updateAnimation,如果这个函数性能不好,很容易卡顿。建议你在 requestAnimationFrame 里更新动画,避免重复渲染:

let ticking = false;
mc.on("panstart panmove", (e) => {
if (e.direction === Hammer.DIRECTION_LEFT) {
this.translateX += e.deltaX;
if (!ticking) {
requestAnimationFrame(() => {
this.updateAnimation();
ticking = false;
});
ticking = true;
}
}
});


4. CSS 硬件加速:确保你的动画元素用了 transform: translate3d,这样 GPU 会介入,动画更流畅:

.your-element {
will-change: transform;
transform: translate3d(0, 0, 0);
}


你可以试试上面这几招组合起来,应该能解决延迟、冲突和卡顿的问题。如果实在搞不定,插件可以帮你省点事,比如 react-motion 或 framer-motion,但原生操作练练也好。
点赞 5
2026-02-07 11:07
素伟~
素伟~ Lv1
手势滑动冲突和延迟的问题,主要是因为浏览器默认行为和hammer.js的事件处理有竞争。代码给你:

const mc = new Hammer(element);
mc.get('pan').set({ threshold: 5, direction: Hammer.DIRECTION_ALL });

// 关键:阻止浏览器默认行为
element.style.touchAction = 'none'; // 这个必须加在正确的地方
element.addEventListener('touchstart', (e) => e.preventDefault(), { passive: false });

mc.on("panstart panmove", (e) => {
if (e.direction === Hammer.DIRECTION_LEFT) {
this.translateX += e.deltaX;
this.updateAnimation();
}
});


再补充一点,如果你的updateAnimation()性能不好,也会影响流畅度。确保动画更新用requestAnimationFrame包裹,别直接暴力改样式。

最后提醒,有时候硬件加速也能帮上忙,在动画元素上加这个:
transform: translateZ(0);

不过别乱加,滥用硬件加速也会出问题。
点赞 14
2026-01-29 20:03