1. 防抖
一段时间内,回调函数只会调用一次。
如果在规定时间内又触发了该事件,则会重新开始算规定时间。
举个栗子,如:窗口滚动scroll事件会在滚动的时候一直触发,比如你滚动了3s,可能触发了几十次printSomething函数。
window.onscroll = function(){printSomething();}
但如果只想在这3s内只触发一次,那么就可以用防抖函数来实现。
//在停止滚动后的200ms后,执行函数
window.onscroll = debounce(printSomething, 200);
实现:
function debounce(fn, delay) {
// let timer = null // 保存定时器
return function (...args) { // 方法1 timer存到函数对象上
clearTimeout(fn.timer)
fn.timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
// return function (...args) { // 方法2
// if (timer) clearTimeout(timer);
// fn.timer = setTimeout(() => {
// fn.apply(this, args)
// }, delay)
// }
}
2. 节流
一段时间内,会每隔一段时间固定调用一次。
如果在规定时间内又触发了该事件,则什么也不做,也不会重置定时器.
function throttle(fn, delay) {
let timer = null;
return function (args) {
if (!timer) {
timer = setTimeout(() => {
timer = null;
fn.apply(this, args)
}, delay)
}
}
}
// 方法2
function throttle(fn, delay) {
let isExecute = false;
return function (...args) {
if (!isExecute) {
isExecute = true;
setTimeout(()=> {
fn.apply(this, args);
isExecute = false;
}, delay)
}
}
}
3.场景
debounce:
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
throttle:
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断