touchmove需节流因其高频触发易致卡顿;推荐requestanimationframe实现帧级节流,仅记录最新位置并延至下帧处理;也可用时间戳手动控制固定间隔;还需在touchend/touchcancel中清理状态。

触摸滑动事件(如 touchstart、touchmove、touchend)在移动端非常频繁,尤其 touchmove 每移动一点就可能触发多次,不加控制容易导致性能问题或逻辑错乱。节流(throttle)是常用手段,核心是限制单位时间内最多执行一次回调。
为什么 touchmove 特别需要节流
touchmove 在手指滑动过程中会高频触发(每毫秒都可能来一个),远比鼠标事件密集。直接在里面做计算、DOM 更新或发请求,极易卡顿。节流不是“防抖”,它不等待停止再执行,而是保证“至少间隔 X 毫秒才执行一次”,适合持续交互场景。
用 requestAnimationFrame 实现轻量节流
这是最推荐的方式——利用浏览器渲染机制,把处理逻辑“对齐”到下一帧,既平滑又高效,且天然节流(每帧最多一次):
- 监听
touchmove,但只记录最新触摸位置,不立即处理 - 用
requestAnimationFrame延迟到下一次重绘前统一处理 - 如果连续触发,中间的调用会被合并,实际只执行最后一次前的状态
示例:
let lastX = 0;
let isAnimating = false;
<p>element.addEventListener('touchmove', (e) => {
const x = e.touches[0].clientX;
lastX = x;</p><p>if (!isAnimating) {
isAnimating = true;
requestAnimationFrame(() => {
// 这里处理滑动逻辑,比如更新 translateX
element.style.transform = <code>translateX(${lastX}px)</code>;
isAnimating = false;
});
}
});</p>
用时间戳手动实现固定间隔节流
若需严格按时间间隔(比如每 16ms 执行一次),可用时间戳判断:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 记录上一次执行的时间戳
- 每次触发时,对比当前时间与上次执行时间差是否 ≥ 设定阈值(如 16ms)
- 满足则执行并更新时间戳;否则跳过
示例(封装成通用节流函数):
function throttle(func, delay) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}
<p>const handleMove = throttle((e) => {
const x = e.touches[0].clientX;
element.style.transform = <code>translateX(${x}px)</code>;
}, 16);</p><p>element.addEventListener('touchmove', handleMove);</p>
注意 touchcancel 和边界清理
节流本身不解决事件生命周期问题。记得在 touchend 或 touchcancel 中重置状态,避免残留:
- 清除
requestAnimationFrame的 pending 状态(如有) - 重置节流中的时间戳或锁标识
- 必要时还原样式或取消动画
例如,在 touchend 中调用一次最终定位,再清空缓存变量,确保交互收尾准确。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










