原生js函数防抖

 函数防抖主要就是防止频繁触发事件就会频繁触发回调,回调要是操作dom或者其他耗时工作,浏览器受不了。

函数防抖:

好比电梯需要上人,来一个人,就要等几秒再走,再来个人又要多等一样的时间,再来一样。

在网上看到也有个比较恰当的比喻,好比网络游戏法师施法,点击之后正在读进度条,你又点了一次,那只能从头再读,每次点都得从头读。

实现代码如下:

function debounce (func, wait) {
  var lastCallTime
  var lastThis
  var lastArgs
  var timerId
  function startTimer (timerExpired, wait) {
    return setTimeout(timerExpired, wait)
  }

  function remainingWait(time) {
    const timeSinceLastCall = time - lastCallTime
    const timeWaiting = wait - timeSinceLastCall
    return timeWaiting
  }

  function shoudInvoking (time) {
    return lastCallTime !== undefined && (time - lastCallTime >= wait)
  }

  function timerExpired () {
    const time = Date.now()
    // 一个劲猛点的话这个if里永远满足不了条件,只有你停下来等一会,就会有结果了
    if (shoudInvoking(time)) {
      return invokeFunc()
    }
    timerId = startTimer(timerExpired, remainingWait(time))
  }

  function invokeFunc () {
    timerId = undefined
    const args = lastArgs
    const thisArg = lastThis
    let result = func.apply(thisArg, args)
    lastArgs = lastThis = undefined
    return result
  }

  function debounced (...args) {
    let time = Date.now()
    lastThis = this
    lastArgs = args
    lastCallTime = time
    // invokeFunc函数没结果之前,再点击多少次下边这个函数都不执行了.点击只会更改lastCallTime
    // 更改了lastCallTime,
    if (timerId === undefined) {
      timerId = startTimer(timerExpired, wait)
    }
  }

  return debounced
}

window.addEventListener('click', debounce(function (event) {
  var p = document.createElement('p')
  p.innerHTML = 'trigger'
  document.body.appendChild(p)
  return 'aaaa'
}, 500))

可以使用lodash 中的 debounce函数。省去自己写的麻烦。但是原理了解一下,没坏处。

原创文章 112 获赞 173 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_41229588/article/details/105844066