防抖函数:

  • 要实现的效果是在页面的input中不停的输入内容,停止输入1秒钟后在控制台输出输入结果(进行相关的数据操作...)
  • 要实现该效果需要用到定时器来触发相应的处理逻辑

    • 但是在做的时候发现使用了setTimeout后依旧是输入一次就处理(输出)一次,只是有些延迟而已,这样就没有意义了
    • 思路:需要将setTimeout存起来,然后每次input触发的时候就清除上一次存下的setTimeout,这样在最后一次触发的时候就只触发了一个setTimeout就实现了防抖的效果
    • 实现方法:将setTimeout通过闭包的形式给存储起来,每次Input触发事件的时候使用clearTimeout清除上一个,代码如下:
<body>
  <input type="text" id="int">

  <script>
    let int = document.querySelector('#int')
    const logRes = function(){ //输出数据
      console.log(int.value)
    }

    const debunce = function(callback ,delay){
      let timer = null
      return function(){
        clearTimeout(timer)   //清空上一次存储的定时器
        timer = setTimeout(() => {
          callback()  //每次防抖结束要执行的回调方法
        }, delay)
      }
    }

    int.addEventListener('input', debunce(logRes, 1500))
  </script>
</body>

节流函数

  • 本次实现的效果是监听 window 的鼠标移动事件,第一次输出坐标后,保持移动,10秒内不再进行输出
  • 思路:函数内部声明两个变量

    • last:用于记录,第一次/上一次输出坐标的时间戳,通过判断 last 的值来确认是不是第一次执行函数

      • 如果第一次执行函数将当前的时间戳赋值给 last
      • 如果 last 有数据,证明不是第一次执行,判断 now < last + delay 当前的时间是否满足大于 上次执行的时间+设定的节流延时时间 的条件,满足则证明已经超过了延时时间可以再次执行,如果不满足则不做任何操作。
    • deferTimer:一个定时器
<body>
<script>
  (function(){
    console.log(arguments);
  })()
  const throttle = function(callback, delay){
    let last    //记录最后的时间
    let deferTimer    //定时器
    return function(){
      let that = this   //向外查找,最终指向 window
      let _args = arguments
      let now = +new Date()   //拿到现在的时间戳
      //判断节流
      //last 用于判断之前是否执行过,看是不是第一次执行
      //now < last + delay 判断设置的时间有没有到,如果时间已经过了,就再执行一次,否则不执行回调
      if (last && now < last + delay){  //不是第一次触发
        clearTimeout(deferTimer)  //清除定时器
        deferTimer = setTimeout(() => {  //重新计时
            last = now   //将最后一次计算的时间改写为当前时间
            callback.apply(that, _args) //在这里直接调用callback是拿不到对应的数据的,使用 apply 将作用域指向 window
        }, delay)
      }else {   //第一次触发
        last = now
        callback.apply(that,_args)
      }
    }
  }
  const moveFun = function(e){
    console.log('鼠标距离页面页面横向距离',e.pageX);
    console.log('鼠标距离页面页面纵向距离',e.pageY);
  }

  //添加监听事件
  window.addEventListener('mousemove', throttle(moveFun, 3000))

</script>
</body>

是在vue项目中使用的防抖和节流函数:

const debounce =(func,delay)=>{
  var timer = null;
  return function() {
      var context = this;
      var args = arguments;
      if (timer) {
          clearTimeout(timer)
      }
      timer = setTimeout(function() {
          func.apply(context, args);
          timer = null;
      }, delay);
  }
}

const throttle =(func,delay)=>{
  var timer = null;
  return function() {
      var context = this;
      var args = arguments;
      if (!timer) {
          timer = setTimeout(function() {
              func.apply(context, args);
              timer = null;
          }, delay);
      }
  }
}

export { debounce,throttle }

调用方式:

<template>
  <div>
    <button @click="test">点我测试</button>
    <button @click="logmsg">测试节流</button>
  </div>
</template>

<script>
import request from '@/api/apiTest.js'
import { debounce,throttle } from '@/utils/debounce.js'
export default {
methods: {
  //测试防抖
  test: debounce(() => {
    request.testGet('pc/fee/bill/load-scheme', {
      name: 'sss'
    }).then(res => {
      console.log('请求成功', res);
    }).catch(err => {
      console.log('清iq失败', err);
    })
  }, 1500),
  //测试节流
  logmsg: throttle(() => {
    console.log('test');
  },1500)
}
}
</script>

<style>

</style>

张嘀嗒
9 声望2 粉丝

一个前端小白,更新学习笔记~~