鼠标移动适合用节流而非防抖,因节流保证每n毫秒至少执行一次,兼顾响应性与性能;防抖则需停止触发才执行,无法满足mousemove持续响应需求。

在鼠标移动(mousemove)事件中直接绑定处理逻辑,容易因高频触发导致性能问题。节流(throttle)能有效控制执行频率,让函数按固定间隔最多执行一次,比防抖更适用于需要持续响应但又不能过于频繁的场景(比如拖拽、滚动位置计算、鼠标轨迹采样等)。
为什么鼠标移动适合用节流而不是防抖
防抖会在停止触发后才执行,而 mousemove 持续移动时几乎不会“停止”,导致回调长期不执行,失去实时响应意义;节流则保证每 N 毫秒至少执行一次,兼顾响应性与性能。
手写一个简单可靠的节流函数
核心思路:记录上一次执行时间戳,每次触发时对比当前时间,仅当间隔超过设定阈值才执行并更新时间戳。
function throttle(fn, delay) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}在 mousemove 中使用节流的正确方式
注意绑定的是节流后的函数,且避免重复包装;推荐在事件监听前一次性创建,而非在回调内反复调用 throttle。
- ✅ 正确:节流函数只创建一次,再传给
addEventListener - ❌ 错误:在回调里每次调用
throttle(handler, 16),会不断新建闭包,且无法共享lastTime
const handleMove = throttle((e) => {
console.log('X:', e.clientX, 'Y:', e.clientY);
}, 16); // 约 60fps
<p>document.addEventListener('mousemove', handleMove);</p>补充建议:结合 passive 和 cancelable 控制行为
若只是读取坐标、不调用 e.preventDefault(),可加 { passive: true } 提升滚动/移动性能;如需阻止默认行为(例如自定义拖拽),则用 { capture: false, passive: false } 并确保兼容性。
- 普通坐标获取 → 推荐
{ passive: true } - 需要调用
e.preventDefault()→ 必须设passive: false,且现代浏览器需在添加监听前声明
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











