防抖节流

107 阅读2分钟
防抖: 防抖是指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。(就是在触发某个事件后,在下一次触发之前,中间的间隔时间如果超过设置的时间才会发送请求,一直触发就不会发送请求)

应用场景:

  • scroll事件滚动触发,

  • 搜索框输入查询

  • 表单验证

  • 按钮提交事件

  • 浏览器窗口缩放,resize事件

    代码示例

    function scrollHandler() {  console.log('滚动了')}window.addEventListener('scroll', scrollHandler)​function debounce(fn, wait) {  var timeout  //闭包的方式定义一个全局变量,是实现防抖函数的核心  return function () {    var context = this,    args = arguments    clearTimeout(timeout)​    timeout = setTimeout(function () {      fn.apply(context, args)    }, wait)  }}window.addEventListener('scroll', debounce(scrollHandler, 500))
    

    理解难点:

    a)逻辑过程是, 定义一个setTimeout事件, 假如在触发之前,又发生了scroll事件的话, 通过clearTimeout函数清除之前定义的setTimeout事件,同时又再次定义一个setTimeout定时事件,从而达到防抖的功能。 b) debounce(scrollHandler, 500),这句代码返回的是一个函数,并没有显式传递参数进去,为什么还要特意用args = arguments这句话特意的接受一下参数, 原因是因为js引擎会自动的传递event事件参数,所以用args = arguments这句话是为了接受event等默认传递的参数。

    花边:

    • 常见操作
    • 复杂操作
节流: 节流是指如果持续触发某个事件,则每隔n秒执行一次。

主要应用场景:

  • DOM元素的拖拽功能实现

  • 射击游戏类

  • 计算鼠标移动的距离

  • 监听scroll事件

    代码示例

    function throttle(fn, wait) {  let timeout;  return function () {    let context = this    let args = arguments    if (!timeout) {      timeout = setTimeout(function() {        timeout = null        fn.apply(context, args)      }, wait)    }  }}
    

    理解难点:

    基本的逻辑是对timeout进行判断, 只有为空才能设置setTimeout事件,从而达到了一个周期只执行一次回调函数的功能,不过这个函数,并没有立即执行的功能。

花边:

  • 常见操作
  • 复杂操作
总结

函数节流与函数防抖都是为了限制函数的执行频次,都是一种性能优化的方法。区别是防抖是有条件的周期性动作,而节流是无条件的周期性动作。两者实现的核心都依赖于闭包

学习链接