防抖与节流
kying-star的博客
# 防抖与节流
# 防抖
事件响应函数在一段时间后才执行
如果在这段时间内在此调用,则重新计算执行时间。
当预定的时间内没有再次调用,则执行响应逻辑。
也就是说在事件触发结束后。在调用响应函数
举例
就相当于开车,当乘客都上完之后才会开车,这就是防抖
实现防抖
debounce()
第一版
function debounce(func,wait){
let timeout;
return function(){
clearTimeout(timeout);
timeout = setTimeout(func,wait);
}
}//函数防抖
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(){//触发函数
console.log(this)//windows{}
container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething,300)
//问题dosomething()中this指向的是windows{}
解决方式如下
function debounce(func,wait){
let timeout;
console.log(`this${this}`);
return function(){
let context = this;
clearTimeout(timeout);
timeout = setTimeout(function(){
func.apply(context);
},wait);
}
}
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(event){
console.log(event)//undefined
console.log(this)
container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething,300)
通过apply改变func中的this的指向,让他指向触发事件的容器
但是还有问题没有解决,我们还不能获取事件对象
解决方法
function debounce(func,wait){
let timeout;
console.log(`this${this}`);
return function(){
let args = arguments
let context = this;
clearTimeout(timeout);
timeout = setTimeout(function(){
func.apply(context,args);
},wait);
}
}
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(event){
console.log(this)
console.log(event)
container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething,300)
利用arguments获取事件对象,附加到apply中
进一步优化
function debounce(func, wait,immediate) {
let timeout;
return function () {
let args = arguments
let context = this;
clearTimeout(timeout);
if (immediate) {
callnow = !timeout;
timeout = setTimeout(()=>{
timeout = null;
},wait)
if(callnow) func.apply(context,args)
} else {
timeout = setTimeout(function () {
func.apply(context, args);
}, wait);
}
}
}
var container1 = document.querySelector('.container');
var count = 0;
function dosomething(event) {
console.log(this)
console.log(event)
container1.innerHTML = count++;
}
container1.onmousemove = debounce(dosomething, 300, true)//立即执行
增加可以设定函数的状态,ture为放抖,false为立刻执行后防抖。
此时代码的健壮性已经很不错了,,但还有优化的余地
返回值和取消操作的实现
明天写