漂亮的防抖与节流
防抖三个阶段
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号