JavaScript 防抖和节流
防抖
防抖基本概念
任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。
我们加入了防抖以后,当你在频繁的输入时,并不会发送请求,只有当你在指定间隔内没有输入时,才会执行函数。如果停止输入但是在指定间隔内又输入,会重新触发计时。
防抖前(图)
防抖后(图)
防抖代码展示
<input type="text" name="" id="" />
<script>
//防抖:用户触发事件,只要最后一次事件的操作
let inp = document.querySelector('input')
inp.oninput = debounce (function() {
console.log(this.value)
},500)
//闭包原理
function debounce(fn,delay) {
let t = null //因为闭包,t不会被销毁
return function () { //return返回值是一个内部函数
if(t !== null) {
clearInterval(t)
}
t = setTimeout(()=> {
fn.call(this);//this通过call改变成和debounce函数一样的指向
},delay);
}
}
实现原理
防抖实现原理就是利用定时器,函数第一次执行时设定一个定时器,并且通过闭包缓存起来,之后调用时发现已经设定过定时器就清空之前的定时器,并重新设定一个新的定时器,如果存在没有被清空的定时器,当定时器计时结束后触发函数执行。
防抖使用场景
频繁触发按钮点击事件、input框搜索等等。
在这里做一个形象的比喻:防抖就是法师发技能的时候要读条,技能读条没完再按技能就会重新读条。
节流
节流基本概念
规定在一个单位时间内只能触发一次函数,如果在单位时间内触发多次,只执行一次。比如两秒内的点击事件,无论点多少次,两秒内只执行一次。
节流前(图)
节流后(图)
节流代码展示
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<script>
//节流:控制执行次数
//控制高频事件的执行次数
window.onscroll = throttle(function () {
console.log('111')
}, 500)
//闭包原理
function throttle(fn, delay) {
let flag = true
return function () {
//return返回值是一个内部函数
if (flag) {
setTimeout(() => {
fn.call(this) //this通过call改变成和debounce函数一样的指向
flag =true
}, delay)
}
flag = false
}
}
</script>
</body>
实现原理
就是通过一个布尔类型变量来判断是否可执行回调,当变量为true时,生成一个定时器,同时将变量取反通过闭包保存起来,当定时器执行完回调后,再将变量变为true,在变量为期false间,调用节流函数不会生成定时器。
节流在工作中的应用
- 懒加载要监听计算滚动条的位置,使用节流按一定时间的频率获取。
- 用户点击提交按钮,假设我们知道接口大致的返回时间的情况下,我们使用节流,只允许一定时间内点击一次。