• 前端都应该要掌握的防抖和节流


    说到防抖和节流相信大家都不陌生,这两个东西大家可能多多少少都有用到过,最少也有听过

    古人云,温故而知新。虽然可能已经很熟悉防抖和节流了,但不妨再看一看巩固一下知识

    什么?你说你不仅不会手写防抖和节流,也没有听过。那也没事,下文会详细介绍的

    防抖和节流有什么用?

    简单来说,防抖和节流都是用来减少函数执行的频率,以达到优化项目性能或者实现特定功能的效果

    防抖

    定义:事件被触发一定时间后再执行回调。如果在这段时间内又被触发了,则重新开始计算时间

    常用场景

    • 输入框远程查询事件
    • 在线文档自动保存
    • 浏览器视口大小改变

    例子

    张三在某平台搜索一本书籍,发现搜索建议并不是瞬间就出现的,而是自己输入词组结束后出现的。那么该平台在此搜索框可能做了什么操作?

    代码实现

    <body>
      <input type="text" id="searchElement" />
    </body>
    <script>
      const searchElement = document.getElementById('searchElement');
      const debounce = (fn, initial) => {
        let timer = null;
        return () => {
          clearTimeout(timer);
          timer = setTimeout(fn, initial);
        };
      };
    
      searchElement.oninput = debounce(function (event) {
        const value = searchElement.value;
        if (value) console.log(value, '请求值');
      }, 1000);
    </script>
    

    节流

    定义:在单位时间内只触发一次函数,若单位时间内多次触发只有一次生效

    常用场景

    • 按钮提交事件(当然也可做成点击后就loading)
    • 页面滚动事件的触发
    • 累计计算鼠标移动距离

    例子

    张三参加某平台周年庆活动,他选购了某热门饮品并一直点击抢购按钮,却发现并不是每次点击都会有响应的。那么该平台前端可能做了什么限制?

    代码实现

    <body>
      <button type="submit" id="buttonElement">抢购</button>
    </body>
    <script>
      function throttle(fn, interval) {
        let timer;
        return (event) => {
          if (timer) return false;
          timer = setTimeout(() => {
            clearTimeout(timer);
            timer = null;
            fn(event);
          }, interval);
        };
      }
    
      var btnClick = document.getElementById('buttonElement');
      btnClick.addEventListener('click', throttle(function (event) {
        console.log(event, '点击了')
      }, 1000));
    </script>
    

    可以看到,张三疯狂点击抢购,但还是每秒只响应1次

    节流(立即执行)

    细心的同学可能发现了,上面这个代码有个弊端,那就是在张三第一次点击的时候也隔了1秒才响应,这不免也太坑了。正常来说第一次应该直接响应的,并且在连续点击结束后的第一次也应该立即触发,其实想实现这样的效果也不难

    <body>
      <button type="submit" id="buttonElement">抢购</button>
    </body>
    <script>
      function throttle2(fn, interval) {
          let init = false; // 引入一个参数记录状态
          let timer;
          return (event) => {
              if (init) return;
              init = true;
              clearTimeout(timer);
              timer = setTimeout(() => {
                  init = false;
              }, interval);
              fn(event);
          }
      }
    
      var btnClick = document.getElementById('buttonElement');
      btnClick.addEventListener('click', throttle2(function (event) {
          console.log(event, '点击了')
      }, 2000));
    </script>
    

    可以看到第一次点击直接打印,第二次疯狂点击只打印一次,最后一次点击也是直接打印

    引入Lodash实现

    GitHub地址:https://github.com/lodash/lodash
    官方文档:https://www.lodashjs.com/

    防抖

    import _ from 'lodash';
    debounceHandle: _.debounce(function() {
      console.log('业务代码');
    }, 2000, {       // 在n毫秒内触发
      leading: true, // 第一次点击立刻执行,默认为true
      trailing: true // 节流结束后立刻执行,默认为true
    });
    

    节流

    import _ from 'lodash';
    throttleHandle: _.throttle(function() {
      console.log("业务代码");
    }, 2000);
    
  • 相关阅读:
    【OpenMMLab】AI实战营第二期Day5:MMPretrain代码课
    「Redis数据结构」字符串对象String
    视频格式怎么批量转换?5 个批量视频转换器分享
    10 款开源的在线游戏,点开就能玩的那种
    UMC云管理平台下ESB产品升级说明
    【Python】定义函数求解一元二次方程
    C复习-预处理器:define+条件编译+文件包含
    11 - Spring AOP介绍与使用2 - 简单配置
    原生小程序,手机键盘弹出会将输入框文本顶上去
    如何获取JDK Proxy动态代理生成的代理类源代码
  • 原文地址:https://www.cnblogs.com/rainy-night/p/16169285.html