函数防抖和函数节流,两者都是优化高频率执行js代码的一种手段。
- 防抖:任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。
- 节流:指定时间间隔内只会执行一次任务(一定时间内js方法只跑一次)。
当我们在业务逻辑中使用定时器来时间防抖和节流会显得很臃肿,像是一坨翔一样,所以呢我们会把防抖的代码封装成一个函数 在业务逻辑中直接调用就可以了 防抖是怎么实现的呢 ?
在业务场景中大多数防抖用在按钮 和input框 节流最常见的就是页面滚动条监听
用input框举个栗子:
<input type="text">
let inp = document.querySelector('input') //获取dom
let time = null //创建一个定时器初始值
inp.oninput=function () {
//time有值代表定时器一直在触发 防抖的目的就是执行最后一次
if( time !== null){ //判断定时器如果有值就清掉 只执行最后一次
clearTimeout(time)
}
time=setTimeout(()=>{ //最后一次
console.log(this.value);
//业务逻辑代码
} )
}
上面这段代码就是为了执行业务代码 很大一坨 我们利用闭包去封装一哈
<input type="text">
//防抖
let inp = document.querySelector('input')
inp.oninput = doc( function() { //直接调用
// console.log(this);指向window对象
// call改变了 谁调用fn这个this就指向谁
console.log(this.value);
}, 1000)
//利用闭包封装一个计时器
//调用这个函数的时需要传两个参数 第一个就是事件要执行的函数 第二个参数就是要执行的计时器的时间
function doc(fn, delay) {
let time = null //创建一个计时器
return function () {
if (time !== null) { //当计时器有值的时候清掉 重新创建一个
clearTimeout(time)
}
time = setTimeout(() => { //执行 新创建的这一个计时器
fn.call(this)
// call改变了 谁调用fn这个this就指向谁
}, delay)
}
}
封装好后只需要调用就可以了 简简单单那么两行代码就搞定了 清爽无比
节流最常见的就是页面滚动条监听
理解了防抖之后我们直接封装后调用
//节流
body{
height: 2000px;
}
window.onscroll = throttle(function () {
console.log('asd');
},500)
//封装
function throttle(fn,delay) {
let fall = true
return function () {
if (fall) {
setTimeout(() => {
fn.call(this)
fall=true
}, delay)
}
// 执行完setTimeout变成false 不在执行了
// 所以每次执行完后把fall变成true才能在500后继续执行
fall = false
}
}