防抖:
定义:
是指连续触发事件但是在设定的一段时间内中只执行最后一次例如:设定1000毫秒执行,当你触发事件了,他会1000毫秒后执行,但是在还剩500毫秒的时候你又触发了事件,那就会重新开始1000毫秒之后再执行。
记忆核心:从新开始
思路实现:
1.事件函数执行,先创建个定时器
2.把逻辑代码放到定时器中
3.当函数再次触发,清除定时器
4.创建一个新定时器即可
优化:
优化1:把事件处理函数–抽离成独立函数优化
2:封装一个公共的-防抖函数(最后精华)
应用场景:
搜索框搜索输入
文本编辑器实时保存
// 1.把逻辑代码装入到定时器中,设置延迟时间
// 2.清空上一次定时器
$("#ipt").on(
"input",
debounce(function () {
console.log($(this).val());
})
);
// 3.事件函数,抽离出来
//4.逻辑代码,让外部传入(函数体+回调)
// 5.(重要):上面this指向输入框(事件触发者)
function debounce(fn, timeout) {
let timer = null;
return function () {
let context = this;
let args = arguments;
//真正事件处理函数,this:事件触发者(input)
clearTimeout(timer);
timer = setTimeout(() => {
//console.log(this, "sss"); 事件源本身<input id="ipt" type="text" class="ipt" placeholder="请输入要搜索的内容">
fn.apply(context, args); //事件触发者,替换到具体逻辑this值上。如果直接调用fn(),此时的this指向window,通过call指向事件源本身。因为此时是$("#ipt").on调用debounce(),所以return后面的函数this指向事件源,箭头函数的this指向外层函数作用域this的值。
}, timeout);
};
}
节流:
就是指连续触发事件但是在设定的一段时间内中只执行一次函数。例如:设定1000毫秒执行,那你在1000毫秒触发在多次,也只在1000毫秒后执行一次
记忆核心:不要打断
思路实现:
1.事件函数执行,先判断有定时器,则直接return
2.把逻辑代码放到定时器中
3.定时器执行后,置空定时器变量
4.下载事件函数执行时,再创建一个新定时器即可
应用场景:
高频事件例如快速点击、鼠标滑动、resize事件、scroll事件下拉加载
视频播放记录时间等
$(document).on(
"scroll",
throttle(function () {
console.log(
$(document).scrollTop() >=
document.documentElement.scrollHeight -
document.documentElement.clientHeight
);
})
);
//优化2:封装公共->节流函数
function throttle(fn,timeout) {
let timer = null;
return function () {
//真正的事件处理函数(this:事件源) 因为这个函数是在上面的事件源$( document).on被调用的,所以此时的this是指向事件源的
let context = this,
args = arguments;
if (timer) return;
timer = setTimeout(() => {
fn.apply(this,args ); //把this传上去,确保上面函数中this关键字是事件源(上面fn()调用,this就变成了window不对了)
timer = null; //置空,让事件再次触发的时候,重新创建一个定时器
}, timeout);
};
}
总结:
1.防抖:单位时间内,频繁触发事件,只执行最后一次
典型场景:搜索框搜索输入
代码思路是利用定时器,每次触发先清掉以前的定时器(从新开始)2节流:单位时间内,频繁触发事件,只执行一次
典型场景:高频事件快速点击、鼠标滑动、resize事件、scroll事件代码思路也是利用定时器,等定时器执行完毕,才开启定时器(不要打断)
其实,我开发一般用lodash库,利用里面的debounce(防抖)和throttle(节流)来做的