浅析JS防抖和节流

本文介绍了JavaScript中的防抖和节流技术,旨在控制高频事件触发时的实际执行次数,防止过度请求导致服务器阻塞。防抖通过限制实际执行的频率,确保在一定时间内仅执行最后一次操作;而节流则在事件触发时立即执行任务,然后设定时间间隔忽略后续快速触发的事件,确保在网络不阻塞的情况下执行。文中通过代码示例展示了防抖和节流的实现方法。
摘要由CSDN通过智能技术生成

JS防抖和节流

  1. 防抖首先思考一个问题,防抖是如何产生的,抖动的现象又是什么,会造成什么样的影响,我们才能更好的理解防抖
    先聊一下抖动的现象吧,假如现在有一个按钮,用户点一次,浏览器向服务器发起一次请求,返回一个值,!但是,这个用户手抖,喜欢在按钮上一直点,那么就会造成,浏览器一直向服务器发送请求,影造成服务器阻塞。这样明显不好。
    所以就出现了防抖这个说法,就是为了控制用户点击时浏览器实际发送请求的次数。就是说,在1s内点击10次按钮,但这明显是用户手抖,才点了10次按钮,我们只需要发送1次请求就可以,因为这里的返回结果是一样的,假设设置时间间隔为1s,那么就是说在1s内发送10次请求,实际只发送1次请求,只有下一秒,再点击按钮,才会发送第二次请求,每次请求完毕之后都要清空定时器,才能执行下次用户点击事件。
    下面用代码解释:
<body>
  <div class="bg">
    <button class="btn">剁手按钮</button>
  </div>
</body>

首先在body里面定义了一个按钮,接着为按钮添加点击事件,这里用函数返回值,来替代请求服务器的返回结果,以下是JS代码:

<script>
  //首先为button添加点击事件
  const button = document.querySelector('button')
  //定义函数ask 
  function payMoney() {
    console.log('已剁'); console.log(this);
  }
 /*  //定义一个防抖函数debounce,这里传入两个参数,
      func为函数内部执行的函数,delay保存setTimeout的时间间隔*/
  function debounce(func, delay) {
    //定义变量timer为延时的名字,放在函数的外围,定义监听事件的同时定义了timer变量
    //由于作用域链的关系,所有的独立的执行函数都能访问timer变量
    let timer;
    return function () {
      //调整this的指向,让防抖函数this指向button
      let context =this
      let args =arguments
      console.log(args);
      //清除延时
      clearTimeout(timer);
      //在返回函数里面定义有个setTimeout,并且在setTimeout执行payMoney这个函数,
      timer = setTimeout(function () {
        //调整this的指向,让防抖函数this指向button
        func.apply(context,arguments)
        // console.log(context);
      }, delay)
    }
  }
//在防抖函数执行的时候添加参数注明执行payMoney这个函数
  button.addEventListener('click', debounce(payMoney, 1000))
</script>

这样我们就实现了,防抖功能的实现,可以有效解决在开发中遇到手抖的用户造成的问题了。

  1. 节流:防抖和节流一样,都是为了解决响应跟不上触发频率这类问题,如果我们需要统计用户滚动屏幕的行为来做出相应的网页行为,那么就需要进行节流操作了,如果用户不断滚动屏幕,就会不断产生请求,相应也在不断的增加,容易导致网络阻塞。我们就可以在触发事件的时候就马上执行任务,然后设定事件间隔限制,在这段时间内不管用户如何进行滚动都会忽视其操作,在时间到了以后,如何再检测到用户有滚动行为,再次执行任务,并且设置时间间隔。
    2.大体流程如下:
    触发事件 -> 执行任务 -> 设置时间间隔
    如果时间间隔有触发行为,就取消任务
    如果时间间隔有触发行为,就再次执行任务换人设置时间间隔
    接下来用代码实现(JS代码):
/* 监听用户改变页面尺寸事件,并且在改变尺寸的时候相应的背景颜色改变 */
  // 方法一:
  //任务函数,为背景色设置随机值
  function coloring (){
    let r = Math.floor(Math.random() *255);
    let g = Math.floor(Math.random() *255);
    let b = Math.floor(Math.random() *255);
    document.body.style.background = `rgb(${r},${g},${b})`;
  }
  //创建节流函数   参数:执行任务的函数func,延时的参数delay
  function throttle(func,delay){
    //变量time,通过闭包对变量进行操作
    let time;
    return function(){
      //调整this的指向
      let context = this
      let args = arguments
      //time为true则返回,不执行任务
      if(time){
        return;
      }
      //time没有被赋值,或者已经执行完毕了
      time = setTimeout(function (){
        //执行任务函数, 调整this的指向
       func.apply(context,arguments)
        time =null;
      },delay)
    }
  }
  //监听事件为resize,触发的任务函数为coloring,返回throttle,让对象执行coloring函数
  window.addEventListener('resize',throttle(coloring,2000))

第二种方法:用Date(),获取当前时间节点与定义的时间节点做对比,也能实现同样的功能,JS代码如下:

function coloring (){
    let r = Math.floor(Math.random() *255);
    let g = Math.floor(Math.random() *255);
    let b = Math.floor(Math.random() *255);
    document.body.style.background = `rgb(${r},${g},${b})`;
  }

  function throttle(func,delay){
    let pre = 0
    return function(){
      let now =new Date();
      let context = this
      let args =arguments
      if(now -pre >delay){
        func.apply(context,args)
        pre = now
      }
    }
  }
  window.addEventListener('resize',throttle(coloring,2000))

OK,以上内容为个人对防抖和节流的理解,若有问题可以及时指出,定会改正.
PS:参考视频,技术蛋老师

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值