Skip to content

手写节流 throttle

节流 throttle

  • 拖拽一个元素时,要随时拿到该元素被拖拽的位置
  • 直接用 drag 事件,则会频繁触发,很容易导致卡顿
  • 节流:无论拖拽速度多快,都会每隔 100ms 触发一次

开启一个可拖拽的 div

js
<div id="div" draggable="true">可拖拽</div>
<script>const div = document.getElementById('div')</script>

普通的写法,频繁获取

js
div.addEventListener('drag', function (e) {
  console.log(e.offsetX, e.offsetY);
});

使用 setTimeout 增加节奏措施

js
// 使用 setTimeout 增加节奏措施
let timer = null;
div.addEventListener('drag', function (e) {
  if (timer) {
    return;
  }
  timer = setTimeout(() => {
    console.log(e.offsetX, e.offsetY);
    timer = null;
  }, 500);
});

封装一个节流 throttle 函数,注意使用:fn.apply(this, arguments)

js
function throttle(fn, delay = 100) {
  let timer = null;
  return function () {
    if (timer) {
      return;
    }
    // 建议使用,防止 this 和 arguments 作用域问题
    const self = this;
    const args = arguments;
    timer = setTimeout(() => {
      fn.apply(self, args);
      timer = null;
    }, delay);
  };
}
div.addEventListener(
  'drag',
  throttle(function (e) {
    console.log(e.offsetX, e.offsetY);
  }, 200),
);

基于 MIT 许可发布