节流

  • 节流是指在一定时间间隔内只执行一次函数。
  • 当事件持续触发时,函数执行的频率被限制在一定的时间间隔内。
  • 如果在该时间间隔内又触发了事件,那么该事件会被忽略,直到时间间隔结束,函数才会再次执行。
  • 适合处理需要连续触发事件的情况,比如页面滚动、鼠标移动等。
export function throttle(fn, delay) {
  let lastTime = 0 // 上次执行的时间
  return function (...args) {
    let now = Date.now()
    if (now - lastTime >= delay) {
      fn.apply(this, args)
      lastTime = now
    }
  }
}
// 定时器实现
export function throttle (fn, delay=500) {
  let flag = true
  const interval = delay
  return function (...args) {
    if (flag) {
      // 每个函数都有apply方法,调用apply可以改变当前函数的this和参数
      fn.apply(this, args)
      // 修改传入的函数this指向以及传递参数
      flag = false
      setTimeout(() => {
        flag = true
      }, interval)
    }
  }
}
function handleThrottledScroll(event) {
  console.log('滚动中...');
}
const throttledScroll = throttle(handleThrottledScroll, 2000);
window.addEventListener('scroll', throttledScroll);

防抖

  • 防抖是指在一段时间内连续触发的事件只执行一次函数。
  • 当事件触发后,会等待一段时间,如果在这段时间内又触发了相同的事件,则重新计时。
  • 只有在这段时间内没有再次触发事件时,才会执行函数。
  • 适合处理用户输入、搜索框输入等频繁触发事件的情况,以减少不必要的请求或者操作。
export function debounce(fn, delay) {
  let timerId = null // 定时器id
  return function (...args) {
    timerId && clearTimeout(timerId)
    timerId = setTimeout(() => {
      fn.apply(this, args)
      timerId = null
    }, delay)
  }
}
function handleDebouncedInput(event) {
  console.log('输入事件节流中...');
}
const debouncedInput = debounce(handleDebouncedInput, 2000);
document.getElementById('inputField').addEventListener('input', debouncedInput);

节流和防抖的主要区别

节流第一次执行函数,没有延迟直接执行,后面的都固定时间间隔执行一次;
防抖第一次执行函数,有延迟,延迟时间结束之后再执行;

链接

Demo页面