防抖函数手写
当事件被触发时,设定一个定时器,若期间又被触发,则重新设定周期,直到周期结束
//需求:监听浏览器滚动事件,返回当前滚条与顶部的距离
//需求实现(未处理版)
function watchScroll() {
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop
console.log(scrollTop)
}
window.onscroll = watchScroll
//需求实现(debounce处理版)
//如果不做处理,在拖动滚动条时这个函数触发的频率会很高,为了不浪费浏览器性能,这里可以用上防抖函数
/**
* @param fn:需要防抖处理的函数,delay:防抖设置的间隔
* @return function
*/
function debounce(fn, delay) {
let timer = null
//这里用到了闭包,每次onscroll触发都会调用下一行返回的匿名函数,所以timer=null只会执行一次,并且timer会一直保留到闭包函数销毁为止
return function () {
if (timer) {
clearTimeout(timer)
timer = setTimeout(fn, delay)
} else {
timer = setTimeout(fn, delay)
}
}
}
function showTop() {
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log(scrollTop);
}
window.onscroll = debounce(showTop, 1000)
//经过处理,滚动条停止滚动1秒以后,才会打印出滚动条位置
节流函数手写
当事件被触发时,在一定时间内只有第一次触发有效,若期间又被触发则无效,直到周期结束
阀门版
/**
* @param fn:需要节流处理的函数,delay:节流设置的间隔
* @return function
*/
function throttle2(fn, delay) {
let working = false
return function () {
if (working) {
console.log("阀门未开")
} else {
working = true
fn()
setTimeout(function () {
// fn()
working = false
}, delay)
}
}
}
时间戳版
function throttle(fn, delay) {
let last = 0
return function () {
let now = Date.now()
if (now > last + delay) {
fn()
// setTimeout(function () {
// fn()
// }, delay)
last = now
}
else {
console.log("距离上次调用的时间差不满足要求哦")
}
}
}
一般直接引用lodash防抖节流函数即可