节流和防抖的作用
减少代码的执行次数,提升性能优化。
场景:输入框搜索时,onmousemove、onscroll、onresize
防抖(debounce):
解决高频率触发事件的问题,可以让被调用的函数在一次连续的高频操作中只被调用一次
当持续触发事件时,一定时间段内没有再次触发事件,事件处理函数才会执行一次,如果在设定的事件内来触发了事件,就会重新延时。
实现
第一版:简单实现
function debounce(func, wait) {
var timeout;
return function () {
clearTimeout(timeout);
timeout = setTimeout(func, wait);
};
}
// 这样在一秒内连续触发事件,变成了一秒内只会触发一次了
document.querySelector(".box").addEventListener("mousemove", debounce(a, 1000));
// 这样在一秒内连续触发事件,变成了一秒内只会触发一次了
第二版:this
第一版的话,触发事件的回调函数 a 方法中console.log(this) 这个this是指向window的
如图:
当我们触发debounce中的事件func时(就是不使用debounce时),这个时的this应该是指向的 .box 元素的
<div *class*="box"></div>
但是当我们使用debounce的时候,this应该指向window对象
所有我们需要在对应的时间段内将this指向正确的对象
function debounce(func, wait) {
var timeout;
return function () {
let self = this;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(self);
}, wait);
};
}
这样就在触发事件回调函数式就指向了当前元素了
第三版:event对象
JavaScript在在处理事件时,会提供事件对象event对象。
但是第二版实现的,console.log(e)的话只会输出 undefined
所以,来实现一下
function debounce(func, wait) {
var timeout;
return function () {
let self = this;
let args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(self, args);
}, wait);
};
}
试一下:
function a(e) {
console.log(1);
console.log(this);
console.log(e);
}
document
.querySelector(".box")
.addEventListener("mousemove", debounce(a, 1000));
这样就有了event对象了
节流(throttle)
可以减少高频调用函数的执行次数
在一定时间内连续触发事件,只触发一次
function throttle(fn, wait) {
let pre = 0;
return function () {
let self = this;
let args = arguments;
let now = Date.now();
if (now - pre > wait) {
fn.apply(self, args);
pre = now;
}
};
}
函数节流和函数防抖区别
函数节流是减少连续的高频操作函数执行次数 (例如连续调用10次, 可能只执行3-4次)
函数防抖是让连续的高频操作时函数只执行一次(例如连续调用10次, 但是只会执行1次)