节流与防抖函数

x33g5p2x  于2021-12-06 转载在 其他  
字(2.3k)|赞(0)|评价(0)|浏览(133)

节流或防抖

作用: 限制函数执行的次数

1. 防抖

通过 setTimeout 的方式,在一定的时间间隔内,将多次触发变成一次触发。

防抖函数我感觉可以理解为一个升降梯,在电梯门关闭之前,只要有人来,就重新等待相同间隔时间。

这里我们使用点击按钮来模拟防抖函数的作用

当用户点击提交按钮后,触发 debonce()函数

  • 这里使用定时器箭头函数,使用 fn.apply()绑定 this,此时 this 指向按钮实例。
  • 通过 arguments 传递剩余参数
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" />
    <input type="submit" id="input" />

    <script> var btn = document.querySelector("#input") btn.addEventListener("click", debounce(submit)) function submit(e) { console.log(this) console.log(e) } // 防抖 function debounce(fn) { let t = null return function () { // 如果存在计时器 if (t) { clearTimeout(t) } // 定时器 这里要使用箭头函数,当点击按钮后,用于给函数绑定this指向按钮 t = setTimeout(() => { // 这里this指向按钮实例, 且传递arguments参数 fn.apply(this, arguments) }, 1000) } } </script>
  </body>
</html>

但是上述代码存在一定的问题,那就是第一次调用会有延迟

如果我们希望第一次调用无延迟,连续调用阻塞,可以这样做

  • 设置一个状态,判断 t 是否为空,如果为空,则!t 为 true,判断为第一次点击,直接调用 fn()。
  • 如果 t 不为 null,这说明定时器还未执行完毕,如果这时候点击会被组织触发。
function debounce(fn, timer) {
  let t = null
  return function () {
    let firstClick = !t

    if (t) {
      clearTimeout(t)
    }

    if (firstClick) {
      fn.apply(this, arguments)
    }

    t = setTimeout(() => {
      t = null
    }, timer)
  }
}

2. 节流

减少一定时间的触发频率

  • new 一个时间对象,获取当前时间,当前时间减去开始时间>设置的延迟时,可以触发被节流的函数;否则不触发。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" />
    <input type="submit" id="input" />

    <script> var btn = document.querySelector("#input") btn.addEventListener("click", throttle(submit, 2000)) function submit(e) { // console.log(this); // console.log(e); console.log("我是被节流的函数,现在我执行了") } function throttle(fn, delay) { let begin = 0 return function () { let cur = new Date().getTime() console.log(cur - begin) if (cur - begin > delay) { fn.apply(this, arguments) begin = cur } } } </script>
  </body>
</html>

可以看到连续触发的效果,只有超过规定时间才可以触发被节流的函数。

相关文章

微信公众号

最新文章

更多