什么是防抖

函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。如下图,持续触发 scroll 事件时,并不执行 handle 函数,当 1000 毫秒内没有触发 scroll 事件时,才会延时触发 scroll 事件。

防抖应用场景如下

  • 搜索框输入查询,如果用户一直在输入中,没有必要不停地调用去请求服务端接口,等用户停止输入的时候,再调用,设置一个合适的时间间隔,有效减轻服务端压力。
  • 表单验证
  • 按钮提交事件。
  • 浏览器窗口缩放,resize 事件 (如窗口停止改变大小之后重新计算布局) 等。
  • 具体实现

    • 非立即执行版

      JAVASCRIPT
      function debounce(func, wait) {
      let timeout;
      return function () {
      let context = this;
      let args = arguments;
      if (timeout) clearTimeout(timeout);
      timeout = setTimeout(() => {
      func.apply(context, args)
      }, wait);
      }
      }

      非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

    • 立即执行版

      JAVASCRIPT
      function debounce(func,wait) {
      let timeout;
      return function () {
      let context = this;
      let args = arguments;
      if (timeout) clearTimeout(timeout);
      let callNow = !timeout;
      timeout = setTimeout(() => {
      timeout = null;
      }, wait)
      if (callNow) func.apply(context, args)
      }
      }

      立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的

      什么是节流

      函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流通俗解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。如下图,持续触发 scroll 事件时,并不立即执行 handle 函数,每隔 1000 毫秒才会执行一次 handle 函数。

      节流应用场景:

      • 按钮点击事件
      • 拖拽事件
      • onScoll
      • 计算鼠标移动的距离 (mousemove)

      具体实现

      • 时间戳版

        JAVASCRIPT
        function throttle(func, wait) {
        let previous = 0;
        return function() {
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - previous > wait) {
        func.apply(context, args);
        previous = now;
        }
        }
        }

        当高频事件触发时,第一次会立即执行(给 scroll 事件绑定函数与真正触发事件的间隔一般大于 delay,如果你非要在网页加载 1000 毫秒以内就去滚动网页的话,我也没办法 o (╥﹏╥) o),而后再怎么频繁地触发事件,也都是每 delay 时间才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了 (最后一次触发事件与倒数第二次触发事件的间隔小于 delay,为什么小于呢?因为大于就不叫高频了呀 (╹▽╹))。

      • 定时器版

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

        当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到 delay 时间后,定时器执行执行函数,并且清空定时器,这样就可以设置下个定时器。当第一次触发事件时,不会立即执行函数,而是在 delay 秒后才执行。而后再怎么频繁触发事件,也都是每 delay 时间才执行一次。当最后一次停止触发后,由于定时器的 delay 延迟,可能还会执行一次函数。

        节流中用时间戳或定时器都是可以的。更精确地,可以用时间戳 + 定时器,当第一次触发事件时马上执行事件处理函数,最后一次触发事件后也还会执行一次事件处理函数。

      • 定时器 + 时间戳版本

        JAVASCRIPT
         
        // 节流throttle代码(时间戳+定时器):
        var throttle = function(func, delay) {
        var timer = null;
        var startTime = Date.now();
        return function() {
        var curTime = Date.now();
        var remaining = delay - (curTime - startTime);
        var context = this;
        var args = arguments;
        clearTimeout(timer);
        if (remaining <= 0) {
        func.apply(context, args);
        startTime = Date.now();
        } else {
        timer = setTimeout(func, remaining);
        }
        }
        }

        在节流函数内部使用开始时间 startTime、当前时间 curTime 与 delay 来计算剩余时间 remaining,当 remaining<=0 时表示该执行事件处理函数了(保证了第一次触发事件就能立即执行事件处理函数和每隔 delay 时间执行一次事件处理函数)。如果还没到时间的话就设定在 remaining 时间后再触发 (保证了最后一次触发事件后还能再执行一次事件处理函数)。当然在 remaining 这段时间中如果又一次触发事件,那么会取消当前的计时器,并重新计算一个 remaining 来判断当前状态。

      总结

      • 函数防抖

        将几次操作合并为一此操作进行。原理是维护一个计时器,规定在 delay 时间后触发函数,但是在 delay 时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

      • 函数节流

        使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。

      • 区别

        函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数

        而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。

      文章参考

       

JavaScript 中的防抖和节流的更多相关文章

  1. 来聊聊JavaScript中的防抖和节流

    目录 JavaScript防抖和节流 问题还原 防抖 什么是防抖 使用场景 节流 什么是节流 使用场景 JavaScript防抖和节流 问题还原 我们先来通过代码把常见的问题还原: <html& ...

  2. JavaScript中函数防抖、节流

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14565642.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  3. JS中的防抖与节流

    什么是防抖?and什么是节流?一起来开心的学习下吧. 首先什么是防抖:就是在一定的时间内事件只发生一次,比如你点击button按钮,1秒内任你单身30年手速点击无数次,他也还是只触发一次.举个例子,当 ...

  4. Js中的防抖与节流函数

    1.何为防抖与节流函数呢? 1.防抖(debounce):通过setTimeout方式,在一定的时间间隔内,将多次触发的事件转化为一次触发.也就是说当一个用户一直触发这个函数,且每次触发函数的间隔小于 ...

  5. JS中的防抖和节流

    JS-防抖和节流 在进行窗口的resize.scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕.此时我们可以采用debounce(防抖)和 ...

  6. JavaScript函数的防抖和节流

    防抖 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间 思路: 每次触发事件时都取消之前的延时调用方法 function debounce(fn) { let tim ...

  7. 输入防抖 vue # 输入搜索的时候 及时搜索的快速访问接口的 解决方案 vue 中使用防抖和节流

    输入防抖 watch: { value (newVal, oldVal) { if (this.timer) { clearTimeout(this.timer) } this.timer = set ...

  8. JavaScript 中函数节流和函数去抖的讲解

    JavaScript 中函数节流和函数去抖的讲解 我们都知道频繁触发执行一段js逻辑代码对性能会有很大的影响,尤其是在做一些效果实现方面,或者逻辑中需要进行后端请求,更是会导致卡顿,效果失效等结果,所 ...

  9. 使用rxjs以及javascript解决前端的防抖和节流

    JavaScript实现方式: 防抖 触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间:思路:每次触发事件时都取消之前的延时调用方法: 举个例子:做一个自动查 ...

随机推荐

  1. CF1278F Cards

    CF1278F Cards 首先我们知道,一次拿牌的概率是 $ P(i) = \frac 1 m $ ,同时权值是1,所以期望就是 $ \frac{1} m $,拿 $ n $ 次牌贡献是独立的,就是 ...

  2. R语言与医学统计图形【1】par函数

    张铁军,陈兴栋等 著 R语言基础绘图系统 基础绘图包之高级绘图函数--par函数 基础绘图包并非指单独某个包,而是由几个R包联合起来的一个联盟,比如graphics.grDevices等. 掌握par ...

  3. Linux系统的开机启动顺序

    Linux系统的开机启动顺序加载BIOS–>读取MBR–>Boot Loader–>加载内核–>用户层init一句inittab文件来设定系统运行的等级(一般3或者5,3是多用 ...

  4. [转载]ORA-02287: 此处不允许序号

    原文地址:ORA-02287: 此处不允许序号作者:nowhill 转载自 http://blog.sina.com.cn/s/blog_6d496bad01011dyv.html 开发人员反映序列不 ...

  5. 日常Java 2021/10/14

    Java数据结构 Java BitSet类 BitSet类创建一种特殊类型的数组来保存位值,数组大小随需要增加,BitSet(),BitSet(int size) 其中的方法 void and(Bit ...

  6. 3步!完成WordPress博客迁移与重新部署

    本文来自于轻量应用服务器征文活动的用户投稿,已获得作者(昵称nstar)授权发布. 由于现有的服务器已经到期,并且活动已经取消,续费一个月145元比较贵,于是参加了阿里云的活动购买一台轻量应用服务器. ...

  7. adhere, adjust, adjacent

    adhere to stick,不是to here. 在古英语里,stick是twig(细树枝).fasten(想必是用twig来固定).后引申为粘住.stick还有stab, pierce的意思,想 ...

  8. 深入理解mysql锁与事务隔离级别

    一.锁 1.锁的定义     锁即是一种用来协调多线程或进程并发使用同一共享资源的机制 2.锁的分类 从性能上分类:乐观锁和悲观锁 从数据库操作类型上分类:读锁和写锁 从操作粒度上分类:表锁和行锁 2 ...

  9. Mybatis相关知识点(一)

    MyBatis入门 (一)介绍 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code, ...

  10. 如果通过 IP 判断是否是爬虫

    通过 IP 判断爬虫 如果你查看服务器日志,看到密密麻麻的 IP 地址,你一眼可以看出来那些 IP 是爬虫,那些 IP 是正常的爬虫,就像这样: 在这密密麻麻的日志里面,我们不仅要分辨出真正的爬虫 I ...