先说防抖再说节流,我的博客我做主。
防抖
用户触发事件过于频繁,只要最后一次操作。
举例
<input type="text" />
const it = document.querySelector("input");
it.oninput = function () {
console.log(this.value);
};
输入123xyz的时候 浏览器会依次打印当前输入框的值。
通过防抖,我们可以只打印,最后一次输入操作后,输入框的所有值,从而达到对性能优化的效果。
const it = document.querySelector("input");
let t = null;
it.oninput = function () {
if (t !== null) {
clearTimeout(t); //阻止 setTimeout() 方法执行函数
}
t = setTimeout(() => {
console.log(this.value);
}, 500);
};
效果
代码优化
const it = document.querySelector("input");
it.oninput = debounce(function () {
console.log(this.value);
}, 500);
function debounce(fn, delay) {
let t = null;
return function () {
if (t !== null) {
clearTimeout(t); //阻止 setTimeout() 方法执行函数
}
t = setTimeout(() => {
fn.call(this); //改变this指向 不然打印的是undefined
}, delay);
};
}
节流
控制高频事件的执行次数
body {
height: 2000px;
}
window.onscroll = function () {
console.log(1);
};
拖拉滚动条 会连续多次的打印1
我们的目标是: 依旧可以拖拉滚动条,但是降低打印的频率。
window.onscroll = throttle(function () {
console.log(1);
}, 500);
function throttle(fn, delay) {
let flag = true; //一开始是可以执行的
return function () {
if (flag) {
setTimeout(() => {
fn.call(this);
flag = true; //delay时间后 又可以执行了
}, delay);
}
flag = false; //不能执行了
};
}
①一开始可以执行 flag = true
②开始执行任务 setTimeout
③setTimeout没结束时(异步操作) 浏览器已经执行了下一句flag = false
④在flag是false 和 setTimeout还没执行完这个空档 如果新任务进来了 发现flag目前还是false 那新任务不能执行
setTimeout的任务执行结束 setTimeout里的flag变为true了 再进来新任务可以继续执行
然后重复以上