防抖封装
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
参数:
-
- func:事件的回调函数
-
- wait:每次执行回调需要等待的时间
-
- flag(布尔值):是否需要第一次触发事件立即执行(不传入flag则默认为false,不会立即执行第一次)
function debounce(func, wait, flag) {
let timer, args, that;
return function () {
//args包含了func的事件对象,that为func的this指向(应当指向事件源)
args = arguments;
that = this;
let callnow = flag && !timer;
if (callnow) func.apply(that, args); //不传入参数flag这段行代码不执行
clearTimeout(timer);
timer = setTimeout(function () {
timer = null;
if (!flag) func.apply(that, args);
}, wait);
};
}
节流封装
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
方法1:定时器实现:setTimeout()------>首次立即执行
参数:
- func:事件的回调函数
- wait:每次执行回调需要等待的时间
注意点:
事件第一次触发不会立即执行func 定时器会等待时间,但最后一次在预设时间内就算不触发事件,也会执行最后一次
function throttle(func, wait) {
let timer, args, that;
return function (args) {
//args包含了func的事件对象,that为func的this指向(应当指向事件源)
that = this;
args = arguments;
// 把timer作为节流阀 来控制传递的函数是否执行
if (!timer) {
timer = setTimeout(function () {
// 定时器到达预定时间后改变节流阀的状态 来执行下一次传入的回调函数
func.apply(that, args);
timer = null;
}, wait);
}
};
}
方法2:时间戳实现 +new Date()
参数:
- func:事件的回调函数
- wait:每次执行回调需要等待的时间
注意点:
事件第一次触发立即执行一次func 后续在wait时间内只执行一次
function throttle(func, wait) {
let args, that;
let oldTime = 0; // 上一次执行回调的时间戳
return function () {
that = this;
args = arguments;
let time = +new Date(); //当前的触发回调的时间戳
if (time - oldTime > wait) {
func.apply(that, args);
// 执行完成后把此次的执行事件赋值给上一次的时间
oldTime = time;
}
};
}
总结
-
函数防抖和函数节流都是防止某一事件频繁触发
-
函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。
-
debounce应用场景
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
-
throttle应用场景
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断