js节流防抖函数

一、防抖函数:

当我们的回调函数(尤其是异步操作,比如请求数据)在短时间内,被连续调用时,会出现卡顿现象,此时的用户体验下降和性能消耗增大;

所以需要添加防抖函数来解决:在设定的事件间隔,n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时,只执行最后一次操作;这样可以减少对性能的消耗;

可以使用的插件比较多;比如underscore,lodash

  lodash中文文档icon-default.png?t=M7J4https://www.lodashjs.com/underscore中文文档icon-default.png?t=M7J4https://www.underscore-js.com/

二、使用案例

下面简单用计数器演示下,防抖的操作;

当在连续点击计数按钮时,不会连续触发计数;

//css代码
<style>
    div {
      width: 500px;
      height: 500px;
      background-color: pink;
      font-size: 1.25rem;
      font-weight: 700;
      text-align: center;
      line-height: 500px;
    }
</style>

<body>
  <div id="container"></div>
  <button>点我</button>
  <script src="./underscore/underscore.js"></script>
  <script>
    let count = 0;
    let container = document.querySelector('#container');
    let button = document.querySelector('button')

    function countNum(e) {
      count++;
      container.innerHTML = count;
    }
    button.onclick = _.debounce(countNum, 300, true);
  </script>
</body>

三、底层原理简单表示

1.debounce函数的参数有三个:

debounce(func,wait,immidiate);

(1) func 表示事件执行的回调函数;
(2)wait 表示事件延迟执行的等待时间;

(3) immediate 表示的是是否立即执行,参数为true时,表示立即执行;为false时,表示在wait等待时间过后执行;

下面主要对三个参数来分析实现功能:

(1)延时功能使用 settimeout 来实现;

(2)this指向问题,在插件中,回调函数的this指向是指向事件的触发者的;所以在做封装时,需要使用call或者apply来改变this指向问题(不改变的化,this是指向window的),因为debounce函数是事件执行的回调函数,所以在debounce中,this指向是指向事件调用者的,所以使用context来保存this,在返回的函数中,使用call来修改func函数的指向;

(3)event事件的问题,在插件中的event参数是事件的事件的具体类型;在debounce函数中的arguments中是保存了事件调用的信息,所以将argument的事件,使用call方法将参数传递给func;

function debounce(func, wait,immediate) {
  let timeout;
  return function () {
    //在wait时间内,重复触发事件的时候,清除定时器,重新进入wait时间
    // console.log(arguments);//arguments参数是具有事件对象的,所以直接将arguments参数传递给func函数
    let args = arguments[0];
    let context = this;
    // console.log(this);//-->指向调用者
    clearTimeout(timeout) 
    //当immediate参数为true时,是立即执行,不进入延迟操作,即进入第一个if判断分支
    if (immediate) {
      let callNow = !timeout;
      timeout = setTimeout(() => {
        timeout = null;
      }, wait);
      //immediate参数设置为true时,(1)刚开始进来timeout还没有生成,即为undefined,取反为true;就会进入下面的立即调用func函数,即立即执行,延时函数开始计时,生成了一个timeout,所以在wait时间内,再次触发事件的时候,callnow不再是true(因为生成了一个timeout,不再是undefined,取反为false),当wait时间过后,重置了timeout = null,所以wait时间后,再次触发事件时,callNow为true(因为timeout置为null了)
      if(callNow)func.call(context,args)
    } else {
      //当immediate参数是false时,不进入延迟操作函数
        timeout = setTimeout(function () {
        //修改this指向,使用call方法
        func.call(context,args)
      }, wait);
    }
   
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当我们在JavaScript中处理一些频繁触发的事件时,比如窗口调整大小、滚动等,防抖函数节流函数可以帮助我们优化性能。 防抖函数(Debounce)是指在事件触发后等待一段时间后再执行回调函数,如果在等待时间内再次触发了该事件,则重新计时。这样可以避免频繁触发事件导致的性能问题。 以下是一个简单的JavaScript实现防抖函数的例子: ```javascript function debounce(func, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(func, delay); }; } ``` 在上面的例子中,`debounce`函数接受两个参数:`func`是要执行的回调函数,`delay`是等待的时间间隔。返回的函数会在事件触发后等待`delay`毫秒后执行回调函数节流函数(Throttle)是指在一定时间间隔内只执行一次回调函数,无论事件触发多频繁。这样可以控制事件的触发频率,避免过多的计算和渲染。 以下是一个简单的JavaScript实现节流函数的例子: ```javascript function throttle(func, delay) { let timer; return function() { if (!timer) { timer = setTimeout(() => { func(); timer = null; }, delay); } }; } ``` 在上面的例子中,`throttle`函数接受两个参数:`func`是要执行的回调函数,`delay`是时间间隔。返回的函数会在事件触发后等待`delay`毫秒后执行回调函数,但如果在等待时间内再次触发了该事件,则不会重新计时。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值