为什么需要节流和防抖呢
例如:
- 百度输入框,输入框中的内容发生改变时,就会发送服务端请求;
- 若输入hello(连续输入),会发送5次请求,这样会影响浏览器的性能。
- 此时,我们需要改变其发送请求的次数降低浏览器的压力,输入hello发送一次请求就可以。
在js使用函数节流或者函数防抖和函数节流来解决上述问题,下面我们就来了解一下这两种方法
函数防抖
-
什么是函数防抖[debounce]?
函数防抖是优化高频率执行js代码的一种手段
可以让被调用的函数在一次连续
的高频操作过程中只被调用一次
-
函数防抖作用
减少代码执行次数, 提升网页性能 -
函数防抖应用场景
oninput / onmousemove / onscroll / onresize等事件
let oInput = document.querySelector("input");
let timerId = null;
// 输入abc,如果输入a之后紧接着输入b会清理定时器,重新计时
oInput.oninput = function () {
timerId && clearTimeout(timerId);
timerId = setTimeout(function () {
console.log("发送网络请求");
}, 1000);
}
- 防抖函数的封装
function debounce(fn, delay) { // fn = test
let timerId = null;
return function () {
let self = this;
let args = arguments;
timerId && clearTimeout(timerId);
timerId = setTimeout(function () {
// console.log("发送网络请求");
// fn();
fn.apply(self, args); //改变this为点击事件的this,并且接收参数
}, delay || 1000);
}
}
oInput.oninput = debounce(function (event) {
console.log("发送网络请求");
console.log(this);
console.log(event);
}, 5000);
- 实战练习:监视可视区宽度对元素的影响
/*需求: 让div的宽高永远是可视区域宽高的一半*/
let oDiv = document.querySelector("div");
function resetSize(){
let {width, height} = getScreen();
oDiv.style.width = width / 2 + "px";
oDiv.style.height = height / 2 + "px";
}
resetSize();
// 监听可视区域尺寸的变化
/*
window.onresize = function () {
resetSize();
console.log("尺寸的变化");
}
*/
window.onresize = debounce(function () {//用我们封装的防抖函数
resetSize();
console.log("尺寸的变化");
}, 1000);
函数节流
- 在上题中函数防抖只能看到最终状态,不能看到元素的变换过程,如果想要看到我们div元素随着屏幕的变化状态,提升用户的体验,就需要用到我们的函数节流。
-
什么是函数节流[throttle]?
函数节流也是优化高频率执行js代码的一种手段
可以减少高频调用函数的执行次数 -
函数节流作用
减少代码执行次数, 提升网页性能 -
函数节流应用场景
oninput / onmousemove / onscroll / onresize等事件 -
函数节流和函数防抖区别
函数节流
是减少
连续的高频操作函数执行次数 (例如连续调用10次, 可能只执行3-4次)
函数防抖是
让连续的高频操作时函数只执行一次(
例如连续调用10次, 但是只会执行1次)
let oDiv = document.querySelector("div");
function resetSize(){
let {width, height} = getScreen();
oDiv.style.width = width / 2 + "px";
oDiv.style.height = height / 2 + "px";
}
resetSize();
// 监听可视区域尺寸的变化
/*
window.onresize = debounce(function () {
resetSize();
console.log("尺寸的变化");
}, 1000);
*/
let timerId = null;
let flag = true;
window.onresize = function () {
if(!flag){ // if(false) if(true) if(false)
return;
}
flag = false;
timerId && clearTimeout(timerId);
timerId = setTimeout(function () { //只有执行完定时器,才会进行下一次resetSize
flag = true;
resetSize();
console.log("尺寸的变化");
}, 500);
}