场景
最早认识是在一个项目中需要监听页面,即浏览器的滚动;
//监听页面滚动并执行
function myScroll () {
let scrollTop = document.body.scrollTop ||
document.documentElement.scrollTop;
console.log('滚动距离:' + scrollTop);
}
window.onscroll = myScroll;
嘿嘿~,需求轻松搞定,当很快就发现了问题,轻轻滚动函数居然执行数十次,这频率超乎想象......, 没办法,只好找方法解决这问题;
问题的解决
询问度娘,就找到防抖与节流;
防抖(debounce):指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间;
//防抖
function debounce(func, wait=300) {
let timerId;
//使用闭包方法
return function (...args) {
timerId && clearTimeout(timerId);
timerId = setTimeout(() => {
//绑定this指向,滚动才执行函数
func.apply(this, args);
}, wait);
};
};
//监听页面滚动并执行
function myScroll () {
let scrollTop = document.body.scrollTop ||
document.documentElement.scrollTop;
console.log('滚动距离:' + scrollTop);
}
window.onscroll = debounce(myScroll);
这次可以看到滚轮无限滚动只会执行一次函数,满足需求;
节流(throttle):指连续触发事件但是在 n 秒中只执行一次函数;
//节流
function throttle(func, wait=300) {
let timerId;
return function (...args) {
if (!timerId) {
timerId = setTimeout(() => {
timerId = null;
func.apply(this, args);
}, wait);
}
}
}
//监听页面滚动并执行
function myScroll () {
let scrollTop = document.body.scrollTop ||
document.documentElement.scrollTop;
console.log('滚动距离:' + scrollTop);
}
window.onscroll = throttle(myScroll);
同种效果,滚动行为每300ms触发一次,节流方法也减少了函数的触发次数,这里图就省略了......;
总结
严格来说,防抖与节流是前端性能优化的方式,可用在监听页面的滚动、浏览器调整窗口大小、输入框的搜索功能,具体怎么用因人而异,看项目需求,具体问题具体分析。