函数的防抖与节流

一、防抖与节流的联系

        相同点:防抖(Debounce)和节流(Throttle)都是用来控制某个函数在一定时间内触发次数,两者都是为了减少触发频率,以便提高性能以及避免资源浪费

        不同点:节流是第一个说了算,后续都会被节流阀屏蔽掉,防抖是最后一个说了算,前面启用的都会被清除

二、节流函数

        1.定义:节流就是指连续触发事件但是在 n 秒中只执行一次函数,节流会稀释函数的执行频率

        2.分类:        

        (1)使用时间戳实现的节流函数会在第一次触发事件时立即执行,以后每过 delay 秒之后才执行一次,并且最后一次触发事件不会被执行

        节流函数输入一个函数并返回一个函数(高阶函数)

        节流使用闭包,保存上一次触发回调的时间 last,执行函数 func,时间阀值delay

        在要执行 func 时,当前时间与上一次触发时间进行比较,如果时间间隔大于interval(now - last >= interval),执行函数 func.apply(context, args)

// 时间戳方式
// 节流 事件连续触发在n秒内只触发一次
function throttle(func, interval) {
  // last为上一次触发回调的时间
  let last = 0;
  // 将throttle处理结果当作函数返回
  return function() {
    // 保留调用时的this上下文
    let context = this;
    // 保留调用时传入的参数
    let args = arguments;
    // 记录本次触发回调的时间
    let now = Date.now();
    // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
    if (now - last >= interval) {
      // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
      last = now
      func.apply(this, args);
    }
  }
}

        (2)定时器实现的节流函数在第一次触发时不会执行,而是在 interval秒之后才执行,当最后一次停止触发后,还会再执行一次函数

// 定时器方式
function throttle1(func, interval) {
  let sign = true;
  return function() {
    // 在函数开头判断标志是否为 true,不为 true 则中断函数
    if (!sign) return;
    //  sign 设置为 false,防止执行之前再被执行
    sign = false;
    setTimeout(() => {
      func.apply(this, arguments)
      // 执行完事件之后,重新将这个标志设置为 true
      sign = true;
    }, interval)
  }
}

        3.使用场景 

        节流一般用于鼠标的跟随动画实现,scrollresizetouchmovemousemove等极易持续性促发事件的相关动画问题,降低频率

<!-- 节流函数 获取鼠标在元素上的坐标 -->
<style>
  .container {
    width: 100px;
    height: 100px;
    background-color: #3496db;
  }
</style>

<div class="container"></div>

<script>
  function throttle(func, interval) {
    let last = 0;
    return function() {
      let args = arguments;
      let now = Date.now();
      if (now - last > interval) {
        func.apply(this, args);
        last = now
      }
    }
  }
  box.addEventListener('mousemove', throttle(function(e){
    console.log(e.pageX)
  }, 2000))
</script>

三、防抖函数

        1.定义:防抖就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间

<input type="text">
<script>
  // 防抖 事件触发 n 秒后执行一次, 如果在 n 秒内重复触发则重新计算函数执行时间
  function debounce(func, interval) {
    // 设置标识符
    let timer = null;
    return function () {
      // 判断定时器是否存在,清除定时器
      timer && clearTimeout(timer)
      // 重新调用setTimeout
      timer = setTimeout(() =>  {
        func.apply(this, arguments)
        timer = null;
      }, interval)
    }
  }
  let input = document.querySelector('input');
  let inputValue = debounce(inputChange, 1000)
  function inputChange(e) {
    console.log(e.target.value)
  }
  input.addEventListener('keyup', inputValue)
</script>

        防抖函数也是一个高阶函数,也使用了闭包,与节流不同,此处闭包保存的是setTimeout 返回的 timer,用于在后续持续触发之前及时取消定时器

        2.使用场景

        防抖一般用于表单元素的校验,如手机号,邮箱,用户名等,部分搜索功能的模糊查询结果实现

<!-- 防抖函数 表单校验 -->
<input type="text" replacer="请输入内容">
<script>
  let input = document.querySelector('input');
  function debounce(func, interval) {
    let timer;
    return function() {
      timer && clearTimeout(timer)
      let args = arguments;
      timer = setTimeout(() => {
        func.apply(this, args)
        timer = null;
      }, interval)
    }
  }
  input.addEventListener('keyup', debounce(function(event) {
    let regexp = /\d/g;
    if(!regexp.test(event.target.value)) {
      console.log('输入错误')
    } else {
      console.log(event.target.value)
    }
  }, 1000))
</script>

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: JS函数防抖节流是两种不同的技术,用于解决类似的问题。 防抖(debounce)指在一定时间内只执行一次函数,如果在这段时间内再次触发函数,则重新计时。这通常用于用户输入或窗口调整等场景,以防止不必要的计算或请求。 节流(throttle)指在一定时间内只执行一次函数,如果在这段时间内再次触发函数,则忽略。这通常用于限制事件的频率,例如鼠标滚动或网络请求。 总的来说,防抖节流都是为了避免因频繁的事件触发导致的性能问题。 ### 回答2: JS函数防抖节流是两种常用的优化手段,用于控制函数的执行频率,减少不必要的资源消耗。 函数防抖的原理是当事件触发后,不立即执行函数,而是等待一段时间(如1000毫秒),如果在这段时间内没有再次触发该事件,则执行函数;如果在该时间段内再次触发了该事件,则重新计时,等待一段时间后再执行函数函数防抖常用于限制高频率触发的事件,比如输入框中的搜索功能,用户连续输入时,只有在停止输入一段时间后,才会执行搜索操作。这样可以减少请求次数,避免不必要的资源浪费。 函数节流的原理是规定一个单位时间,在这个单位时间内,只能执行一次函数。如果在单位时间内多次触发了该事件,只有第一次触发会执行函数,其他触发会被忽略。函数节流常用于限制高频率触发的事件,比如页面滚动时的加载更多功能,用户快速滚动页面时,只会在固定的时间间隔内触发一次加载更多。 总结来说,函数防抖是等待一段时间后执行函数,期间事件还会重新计时,确保函数只在最后一次触发后执行;而函数节流是按照固定的时间间隔执行函数,不管触发次数多少,只在规定的时间间隔内执行一次函数函数防抖更适合控制高频率触发的事件,而函数节流更适合控制单位时间内触发的次数。 ### 回答3: JS函数防抖节流都是用来控制函数执行频率的技巧,但它们的实现方式和应用场景有所不同。 函数防抖是指在事件触发后,等待一定时间之后再执行函数。如果在这个等待时间内再次触发了该事件,就会重新计时。防抖的主要作用是减少函数执行的频率。常见的应用场景有输入框的关键词搜索,用户在输入过程中频繁触发输入事件,而我们希望用户停止输入后再进行搜索操作。使用函数防抖可以避免用户每输入一个字符都进行搜索,减少服务器负载。 函数节流是指在一定时间间隔内只执行一次函数。相比于函数防抖函数节流更注重于函数执行的间隔时间。如果在指定的时间间隔内多次触发了该函数,只有在间隔时间到达后才会执行函数。常见的应用场景包括页面滚动事件、窗口大小改变事件等。通过函数节流,我们可以控制事件响应的频率,避免过于频繁的函数执行。 总结起来,函数防抖适用于限制函数执行频率,主要用于输入框搜索等场景。而函数节流适用于限制函数连续触发的频率,主要用于页面滚动、窗口大小改变等场景。两者的区别在于对时间的处理方式,一个是等待一段时间后执行,一个是一段时间内只执行一次。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小菜凯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值