1、函数防抖
事件触发之后,函数在n秒内只执行一次,如果在n秒内又触发了一次,则会重新计算函数的执行时间。
函数防抖适用于用户输入、提交按钮的点击事件等;函数防抖的核心就是:在用户不触发事件的时候,才触发行为,并且抑制了本来在事件中的行为。
【代码实现】
// fn:表示需要防抖的函数,wait表示间隔的时间,immediate表示是否立即执行
let debounce = function (fn, wait, immediate){
let timer;// 声明定时器
return function () {
// 该函数是用户每次实际调用的防抖函数
let self = this;// 定义上下文对象
let args = arguments;// 获取函数参数,保证上下文对象不变,且仍然可以使用e参数
// 如果定时器已经存在,就清空定时器,重新定义一个新的定时器,重新计算时间,延迟执行用户传入的方法
if (timer) clearTimeout(timer);
if (immediate) {
let calNow = !timer;
timer = setTimeout(function () {
timer = null;
}, wait)
if (callNow) fn.apply(self, args);// 如果是立即执行的话,那么直接调用函数即可
} else {
timer = setTimeout (function () {
// 执行fn函数
fn.apply(self, args);// 函数的参数
}, wait)// 如果用户触发事件的时间间隔小于wait,那么在函数还没有执行的时候,就已经清空了定时器,开始了重新记录时间,函数行为并不会被执行;
}
}
}
函数防抖的可立即执行:开始的时候,设置一个定时器,只要定时器存在,每次点击就会重新计时,除非时间间隔大于delay,此时,定时器为空,则可以执行函数
2、函数节流
连续触发事件,但是在n秒内,函数只会执行一次,节流会稀释函数的执行频率。函数节流会强制函数以固定的频率执行,适用于resize、mousemove、touchmove、scroll等。
防抖和节流的作用都是防止函数多次调用,二者的区别是:函数防抖是在事件触发结束之后,调用函数;函数节流是每隔一定的时间间隔调用函数。函数防抖是将多次执行变为一次执行;函数节流是以固定的频率执行函数。
【代码实现】
let throttle = function (fn, delay) {
let timer = null;
let previous = 0;
return function () {
let context = this;
let args = arguments;
let now = Date.now();
let interval = now - previous;
if (interval < delay) {
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
} else {
fn.apply(context, args);
previous = now;
}
}
}