js防抖和节流

参考资料

  1. JS深入理解——模拟实现防抖函数
  2. js防抖和节流 区别及实现方式
  3. lodash

前言

抖动和防抖都是用来限制函数的执行频率,以优化函数触发频率过高导致的响应速度更不上触发速度,出现延迟、假死或卡顿的现象。

常见的频繁触发的事件有:

  • 输入框的keyup/keydown
  • 调整窗口大小的resize
  • 页面滚动的scroll
  • 鼠标滑动的mousedown/mousemove

防抖

在高频事件触发后,n秒后执行函数。如果n秒内高频事件再次被触发,则重新计时。

防抖适合在搜索框中应用,即用户输入完后停顿一段时间才发送网络请求。

function debounce(func, delay = 1000) {
  let timeout
  return function () {
    clearTimeout(timeout)
    timeout = setTimeout(() => { // 注意,这里使用的是箭头函数,因此下面的this指向的是被监听的dom元素,而不是window
      func.apply(this, arguments)
    }, delay)
  }
}

const searchInput = document.getElementById('searchInput')
searchInput.addEventListener('keyup', debounce(function (e) {
  console.log('\n执行查询代码');
  console.log(this);
  console.log(e)
}))

更高级的功能就不实现了,比如第一次立即执行,等到n秒后才能重新触发,或者取消防抖等,详细见参考资料1。

节流

在高频事件触发后,立即执行函数。如果n秒内高频事件再次被触发,则拒绝执行函数。

防抖适合在下拉无限加载页面场合应用,不必等到用户停下来才发起网络请求。

function throttle(func, delay = 1000) {
  let canRun = true // 用闭包维护一个变量
  return function () {
    if (canRun === false) return
    canRun = false
    setTimeout(() => {
      func.apply(this, arguments)
      canRun = true
    }, delay)
  }
}

loadash

loadash是一个js的第三方库,其提供了防抖和节流的函数,我们可以用loadash来加快开发效率。

1)模拟用户操作

let index = 0 // 该变量代表用户的输入值
const intervalId = setInterval(function () {
  index++ // 用户输入值加一
  test(index) // 调用test,将用户输入值传入
  if (index === 10) {
    // index到10时模拟结束
    clearInterval(intervalId)
  }
}, 300)

2)测试debounce

// 生成一个debounce函数,只有用户无操作1000毫秒后才会执行传入的函数
const test = _.debounce(function (value) {
  console.log(value)
}, 1000)

输出:

10

3)测试throttle

// 生成一个throttle函数,每隔1000毫秒允许执行传入的函数
const test = _.throttle(function (value) {
  console.log(value)
}, 1000)

输出:

1
4
8
10
上一篇:react 防抖文本框


下一篇:搜索框实时搜索效果