1.防抖与节流为何出现以及是什么?
在日常开发中,我们经常会遇到:如input输入框监听事件,点击按钮事件,鼠标移动事件,视图窗口缩放事件等事件,如果这些事件不做限制的话,会不断触发相应的事件极大的浪费资源,降低前端的性能
这个是时候我们可以引入
防抖(debounce)
和
节流(throttle)
来帮助我们极大的减少高频事件的触发,减少资源的浪费和提高性能;防抖与节流就是为了防止用户高频率的触发某种操作而产生的
2.防抖
防抖:debounce 就是规定在一定的
时间后
触发,如果在此时间内事件被触发,则时间重新计算;例如:定义在3秒后触发事件,3秒内你又触发事件,则时间重新计算,从0开始,还是3秒后触发
适合的场景
:input输入框的监听,我们只希望最后输入完才会去触发查询相应的事件;还有按钮的点击,我们只希望频繁的点击按钮,在最后一次点击后才会触发事件…
我们拿点击按钮触发事件为例:不加防抖的情况:
index.html文件代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button style="color:red;text-align: center;" id="btn">按钮点击我</button>
<script src="./index.js"></script>
</body>
</html>
index.js代码如下:
// 获取按钮的dom元素并且绑定原生点击事件
let btn=document.getElementById('btn')
btn.addEventListener('click',function(){
console.log('我被点击了'+Math.random())
})
频繁的点击按钮,会发现控制台频繁的打印信息
加上防抖函数:
// 获取按钮的dom元素并且绑定原生点击事件
let btn=document.getElementById('btn')
// btn.addEventListener('click',function(){
// console.log('我被点击了'+Math.random())
// })
// 防抖函数 简单的高阶函数 返回一个函数
const myDebounce=function(fn,delay){
let timer=null
let ctx=this
let args=arguments
return function(){
if(timer) clearTimeout(timer)
timer=setTimeout(()=>{
fn.apply(ctx,args)
},delay)
}
}
// 改造加上防抖函数
btn.addEventListener('click',myDebounce(function(){
console.log('我被点击了'+Math.random())
},2000))
此时我们在点击按钮,会发现不管我们如何频繁的点击,控制台并不打印信息,只有停止点击按钮2秒后才会打印出第一条信息
但是我们发现此时并不合理,
我们希望第一次点击时一定触发
,此后在点击按照2秒后触发才合理,是吧?那么我们改造一下,给防抖函数加一个变量来标识是否是第一次触发,代码如下:
// 获取按钮的dom元素并且绑定原生点击事件
let btn=document.getElementById('btn')
// btn.addEventListener('click',function(){
// console.log('我被点击了'+Math.random())
// })
// 防抖函数 简单的高阶函数 返回一个函数
const myDebounce=function(fn,delay){
let timer=null
let ctx=this
let args=arguments
let firstClick=1
return function(){
if(timer) clearTimeout(timer)
if(firstClick===1){
fn.apply(ctx,args)
firstClick++
}else{
timer=setTimeout(()=>{
fn.apply(ctx,args)
},delay)
}
}
}
// 改造加上防抖函数
btn.addEventListener('click',myDebounce(function(){
console.log('我被点击了'+Math.random())
},2000))
3.节流
节流:
throttle,就是 在规定的一段时间后一定会执行一次,时间不会重新计算;就是每隔一定时间执行一次的意思。例如:我们定义在3秒后触发事件,就会每隔3秒触发一次事件
适合的场景是:鼠标移动事件 或者视图窗口调整 需要将多次事件改为一段时间执行一次的事件
这里我们还是以按钮的点击为例:
index.js代码如下:
// 获取按钮的dom元素并且绑定原生点击事件
let btn=document.getElementById('btn')
// 节流函数 简单的高阶函数 返回一个函数
const myThrottle=function(fn,delay){
let flag=true //作为是否执行的开关阀门
let ctx=this
let args=arguments
let firstFlag=1 //第一次执行
return function(){
if(firstFlag===1){
fn.apply(ctx,args)
firstFlag++ //第一次可以执行
}else{
if(flag){
setTimeout(()=>{
fn.apply(ctx,args)
flag=true
},delay)
flag=false
}
}
}
}
// 改造加上节流函数
btn.addEventListener('click',myThrottle(function(){
console.log('我被点击了'+Math.random())
},2000))
点击按钮,我们会发现,第一次点击事件立马执行,然后后面疯狂点击事件,每隔2秒会打印出信息;
4.区别
防抖是多次频繁的触发,变为最后一次执行的触发;
节流是多次频繁的触发,变为每隔一段时间执行的触发;
在项目中我们根据具体的实际情况来选择使用防抖或者节流,来减少资源的浪费,优化前端的性能。
加油,学习前端每一天!!!