防抖和节流

一、 防抖

设定时间内频繁触发,都不会去执行具体业务的代码,只在定时器后执行

封装

//封装功能防抖
function fangdou(callback, delay) {
  var timer;
  return function (e) {
    //返回给addEventListener
    // 2. 如果之前有定时器,则表示之前也有执行过,先将定时器清除
    if (timer) {
      // console.log('清理', timer)
      clearTimeout(timer);
    }
    //1. 创建一个定时器,延时执行代码
    timer = setTimeout(() => {
      //执行回调
      callback(e);
      timer = null; //执行完毕后手动清理
    }, delay);
    // console.log('设置', timer)
  };
}

使用

div.addEventListener(
  "mousemove",
  fangdou(function (e) {
    div.innerText = +div.innerText + 1;
    console.log("event", e);
  }, 300)
);

在 vue 中使用

<script>
function debounce(fn, delay = 300) {
  //默认300毫秒
  var timer;
  // console.log("debounce", timer);
  return function() {
    var args = arguments;
    // console.log("callback", timer);
    if (timer) {
      // console.log("清除了", timer);
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, args); // this 指向vue
      timer = null;
    }, delay);
  };
}
export default {
   data() {},
   methods:{
     // 相当于 onSearch:callback 
    onSearch: debounce(function() {
      if (this.musicInfo !== "") {
        this.publicHttp(
          { keyword: this.musicInfo },
          "post",
          "http://localhost:9999/searchMusic",
          res => {
            console.log(res.data);
            this.list = res.data.data;
          }
        );
      }
    },300),
   },
   // 以下方法没有达到预期效果,
   // 因为执行的是onSearch(),debounce的callback并没有执行
    onSearch2(){
      debounce(()=>{
        // console.log('debounce',this)
        if (this.musicInfo !== "") {
          this.publicHttp(
            { keyword: this.musicInfo },
            "post",
            "http://localhost:9999/searchMusic",
            res => {
              console.log(res.data);
              this.list = res.data.data;
            }
          );
        }
      }, 1000)
    },
}

二、 节流

降低触发的频率,让函数相隔一定的时间后才允许执行,利用两次函数执行的时间差原理

使用

document.addEventListener(
  "scroll",
  jieliu(function () {
    console.log(document.documentElement.scrollTop);
  }, 100)
);

封装

function jieliu(callback, delay) {
  var timestamp = new Date();
  return function () {
    var now = new Date();
    if (now - timestamp > delay) {
      callback.apply(this, arguments);
      //执行后的记录
      timerstamp = new Date();
    }
  };
}
Last Updated:
Contributors: zerojs