JS防抖和节流,手写实现

一、什么是防抖和节流?

函数防抖和节流,都是控制事件触发频率的方法。

防抖:假设函数持续多次执行,我们希望让它冷静下来再执行。也就是当持续触发事件的时候,函数是完全不执行的,等最后一次触发结束的一段时间之后,再去执行。

节流:让函数有节制地执行,而不是毫无节制的触发一次就执行一次。
什么叫有节制呢?就是在一段时间内,只执行一次。
节流顾名思义则是将减少一段时间内触发的频率,指定时间间隔内只会执行一次任务。

防抖场景

  • 文本输入的验证,连续输入文字后发送 AJAX 请求进行验证,验证一次就好。
    • 监听一个输入框的,文字变化后触发change 事件
    • 直接用keyup 事件,则会频发触发change事件
    • 防抖:用户输入结束或暂停时,才会触发change事件
  • 用户快速点击翻页时,只需要执行用户最后一次希望到达的页数即可,中间页数都是用户不希望看到的,使用防抖函数可以有效的减少发送请求的次数

节流场景

  • 懒加载要监听计算滚动条的位置,使用节流按一定时间的频率获取

  • DOM 元素的拖拽功能实现(mousemove)

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

二、初步实现

防抖

const input = document.querySelector('#input');
let timer = null;
input.addEventListener('keyup', function () {
  clearTimeout(timer);
  timer = setTimeout(() => {
    // 模拟触发change事件
    console.log(input.value);
  }, 500);
});

节流

const div1 = document.getElementById('div1');

let timer = null;

div1.addEventListener('drag', e => {
  if (timer) {
    return;
  }
  timer = setTimeout(() => {
    console.log(e.offsetX, e.offsetY);
    timer = null;
  }, 100);
});

三、函数封装

防抖封装

function debounce(fn, delay = 500) {
  // timer 是在闭包中的
  let timer = null;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
}

input.addEventListener(
  'keyup',
  debounce(function () {
    console.log(input.value);
  })
);

节流封装

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

function throttle(fn, delay = 100) {
  let timer = null;
  return function (e) {
    if (timer) {
      return;
    }
    timer = setTimeout(() => {
      fn.apply(this, arguments);
      // fn(e)
      timer = null;
    }, delay);
  };
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值