zoukankan      html  css  js  c++  java
  • js的防抖(debounce) 和 节流(throttling)

    函数防抖和节流,都是控制事件触发频率的方法。应用场景有很多,输入框持续输入,将输入内容远程校验、多次触发点击事件、onScroll等等。
    例子:鼠标滑过一个div,触发onmousemove事件,它内部的文字会显示当前鼠标的坐标。

    <style>
        #box {
          width: 1000px;
          height: 500px;
          background: #ccc;
          font-size: 40px;
          text-align: center;
          line-height: 500px;
        }
    </style>
    
    <div id="box"></div>
    
    <script>
      const box = document.getElementById('box')
      box.onmousemove = function (e) {
        box.innerHTML = `${e.clientX}, ${e.clientY}`
      }
    </script>

    效果是这样的:

    在上边的场景下,我们不希望触发一次就执行一次,这就要用到防抖或节流。下面我们看一下它们能为我们做什么吧。

    防抖

    函数防抖,这里的抖动就是执行的意思,而一般的抖动都是持续的,多次的。假设函数持续多次执行,我们希望让它冷静下来再执行。也就是当持续触发事件的时候,函数是完全不执行的,等最后一次触发结束的一段时间之后,再去执行。先看一下效果:

    代码实现:

    function debounce(func, delay) {
      let timeout
      return function() {
        clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
        timeout = setTimeout(() => {
          func.apply(this, arguments)
        }, delay)
      }
    }

    用法:

    box.onmousemove = debounce(function (e) {
        box.innerHTML = `${e.clientX}, ${e.clientY}`
      }, 1000)

    节流

    节流的意思是让函数有节制地执行,而不是毫无节制的触发一次就执行一次。什么叫有节制呢?就是在一段时间内,只执行一次。效果是这样的:

    代码实现:

    function throttle(func, delay) {
    //throttle函数只是提供了一个作用域,内部用闭包声明了一个run的开关变量,由于闭包的存在,run这个变量会一直存在不被销毁,而let run = true只在这个闭包(可以理解为作用域)内只声明了一次,但它不会被持续执行,所以return的函数内部的判断不会被它覆盖掉。 let run
    = true return function () { if (!run) { return // 如果开关关闭了,那就直接不执行下边的代码 } run = false // 持续触发的话,run一直是false,就会停在上边的判断那里 setTimeout(() => { func.apply(this, arguments) run = true // 定时器到时间之后,会把开关打开,我们的函数就会被执行 }, delay) } }

    调用的时候:

    box.onmousemove = throttle(function (e) {
      box.innerHTML = `${e.clientX}, ${e.clientY}`
    }, 1000)

    这样,就实现了节流,节流还可以用时间间隔去控制,就是记录上一次函数的执行时间,与当前时间作比较,如果当前时间与上次执行时间的时间差大于一个值,就执行。

    总结

    防抖和节流巧妙地用了setTimeout,来控制函数执行的时机,优点很明显,可以节约性能,不至于多次触发复杂的业务逻辑而造成页面卡顿。

     参照:https://zhuanlan.zhihu.com/p/72923073

  • 相关阅读:
    前端基础(2)CSS
    前端基础(1)、HTML
    MySQL数据库,这一篇就够啦!!!(持续更新)
    十、数据库之流程控制
    九、数据库之存储过程和函数
    spring注解总结
    eclipse导入项目后错误的处理方式
    ssm分页查询错误
    字节编址和字的区别(转)
    数据库查询练习
  • 原文地址:https://www.cnblogs.com/vickylinj/p/14170583.html
Copyright © 2011-2022 走看看