漂亮的防抖与节流
防抖三个阶段
1.1s后执行1次,多次点击不执行
2.首次点击执行,多次点击只执行第一次,(执行1次)
3.首次点击执行,多次点击只执行最后一次,(执行2次)
1-
 
<template>
  <div>
    <el-button id="btn">catchMe</el-button>
  </div>
</template>
<script>
export default {
  mounted() {
    let btn = document.getElementById("btn");
    btn.addEventListener("click", trigger(real, 1000));
    function trigger(fn, delay) {
      let time = null;
      return function () {
        // *FirstClick execute.
        // let firstClick = !time;
        // firstClick && fn(...arguments);
        if (time) {
          clearTimeout(time);
        }
        // reset timer(定时器clock)
        // now time is not null, firstClick is null
        // But it should be null when the next time to click.
        time = setTimeout(() => {
          // *firstClick become the start flag to clickMethod.
          fn(...arguments);
        //   time = null;
          // **When timer clear and the last click need to be executed.
        //   !firstClick && fn(...arguments);
        }, delay);
      };
    }
    function real(e) {
      console.log("debounce", e);
    }
  },
};
</script>
2-
 
<template>
  <div>
    <el-button id="btn">catchMe</el-button>
  </div>
</template>
<script>
export default {
  mounted() {
    let btn = document.getElementById("btn");
    btn.addEventListener("click", trigger(real, 1000));
    function trigger(fn, delay) {
      let time = null;
      return function () {
        // *FirstClick execute.
        let firstClick = !time;
        firstClick && fn(...arguments);
        if (time) {
          clearTimeout(time);
        }
        // reset timer(定时器clock)
        // now time is not null, firstClick is null
        // But it should be null when the next time to click.
        time = setTimeout(() => {
          // *firstClick become the start flag to clickMethod.
        //   fn(...arguments);
          time = null;
          // **When timer clear and the last click need to be executed.
        //   !firstClick && fn(...arguments);
        }, delay);
      };
    }
    function real(e) {
      console.log("debounce", e);
    }
  },
};
</script>
3-
 
<template>
  <div>
    <el-button id="btn">catchMe</el-button>
  </div>
</template>
<script>
export default {
  mounted() {
    let btn = document.getElementById("btn");
    btn.addEventListener("click", trigger(real, 1000));
    function trigger(fn, delay) {
      let time = null;
      return function () {
        // *FirstClick execute.
        let firstClick = !time;
        firstClick && fn(...arguments);
        if (time) {
          clearTimeout(time);
        }
        // reset timer(定时器clock)
        // now time is not null, firstClick is null
        // But it should be null when the next time to click.
        time = setTimeout(() => {
          // *firstClick become the start flag to clickMethod.
          // fn(...arguments);
          time = null;
          // **When timer clear and the last click need to be executed.
          !firstClick && fn(...arguments);
        }, delay);
      };
    }
    function real(e) {
      console.log("debounce", e);
    }
  },
};
</script>
节流
高强度点击按钮,每1s生成一次提示
时间戳版本
 
<template>
  <div>
    <el-button id="btn">needYou</el-button>
  </div>
</template>
<script>
export default {
  mounted() {
    let btn = document.getElementById("btn");
    btn.addEventListener("click", trigger(real, 1000));
    function trigger(fn, delay) {
      // last executed time
      let bef = 0;
      return function () {
        // get recent time
        let now = new Date().getTime();
        // When time has arrived, it exectues and bef reset.
        if (now - bef > delay) {
          fn(...arguments);
          bef = now;
        }
      };
    }
    function real() {
      console.log("I need you.");
    }
  },
};
</script>
定时器版本
 
<template>
  <div>
    <el-button id="btn">needYou</el-button>
  </div>
</template>
<script>
export default {
  mounted() {
    let btn = document.getElementById("btn");
    btn.addEventListener("click", trigger(real, 1000));
    function trigger(fn, delay) {
      let flag = true;
      return function () {
        // Frist click, it will delay to execute.
        flag &&
          setTimeout(() => {
            fn(...arguments);
            flag = true;
          }, delay);
        // Flag become false, timer will not start.
        // Until the next time click.
        flag = false;
      };
    }
    function real() {
      console.log("I need you.");
    }
  },
};
</script>
使用
对一个el-button使用防抖,多次点击只执行首次
// DebounceBtn.vue
 
<template>
  <div>
    <el-button class="click">click</el-button>
    count:{{ count }}
  </div>
</template>
<script>
import { debounce } from "../utils/utils";
export default {
  data() {
    return {
      count: 0,
    };
  },
  mounted() {
    let btn = document.getElementsByClassName("click")[0];
    btn.addEventListener("click", debounce(this.handleClick, 1000));
  },
  methods: {
    handleClick() {
      this.count = this.count + 1;
    },
  },
};
</script>
<style>
</style>
// /utils/utils.js
 
/** * @param {Function} func * @param {number} wait * @param {boolean} immediate * @return {*} */ export function debounce(func, wait) { console.log('debounce count'); let time = null; return function () { let firstClick = !time; firstClick && func(...arguments); if (time) { clearTimeout(time); } time = setTimeout(() => { time = null; }, wait) } }

可用防抖版本

总结——
防抖就是通过setTimeout 的方式,在一定的时间间隔内,将多次触发变成一次触发 。
节流:就是减少一段时间的触发频率。
防抖与节流最大的区别就是,无论事件触发多么频繁,都可以保证在规定时间内可以执行一次执行函数。防抖首尾自定义执行,节流点击途中一直有隔着相应时间间隔的执行。
    人生到处知何似,应似飞鸿踏雪泥。
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号