在前端开发中,频繁的触发事件执行,对于dom操作、资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃。函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的
1.防抖
函数防抖就是在函数需要频繁触发情况时,只有足够空闲的时间,才执行一次,
如下图
防抖应用比较多是实时搜索,没有防抖的例子如下
<input type="text">
<script>
let inputD = document.querySelector('input');
inputD.oninput = function(){
ajax(this.value)
}
function ajax(value){
console.log(value)
}
</script>
可以看到,只想搜索nba,却连续搜索了n,nb,nba。没有防抖会浪费许多浏览器资源
现在加上防抖
oninput = debounce(handle,1000);//handle是我们要执行的事件函数,1000是要空暇1000ms
function debounce(handle,delay){
let timer = null;//用来记录定时器
return function(){//返回触发事件执行的函数
let _self = this;//用来指向触发事件的dom对象
let arg = arguments;//用来指向触发事件的事件对象
//每次返回函数都要将之前的定时器清楚
clearTimout(timer);
timer = setTimerout(function(){
handle.applay(_self,[arg])
},delay)
//es6则可以不用去声明_self与arg
timer=setTimeout(()=>{
//箭头函数没有this和arguments,这里的this和arguments全都是外部函数的
handle.apply(this,arguments)
},delay)
}
}
function handle(e){
ajax(this.value);
console.log("事件对象:"+e)
}
function ajax(value) {
console.log(value)
}
效果如下:
2.节流
函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。如下图
节流应用比较多是发送ajax请求,频繁的ajax请求会降低浏览器性能,所以在一各周期内只能发送一个请求是最好的
<div>发送了几次ajax请求<span id="count">0</span></div>
<button id="btn">click</button>
<script>
btn.onclick = throttle(handle,1000);
function throttle(handle,wait){
//跟防抖差不多,不过节流用到是时间戳
let lastTime = 0;
return function(){
let now = Date.now();
if(now-lastTime>=wait){//大于等于一个周期后才会执行
handle.apply(this,[arguments]);
lastTime = Date.now()
}
}
}
function handle(){
count.innerText = Number(count.innerText)+1;
}
</script>
效果如下
如果不加节流,就会发送成百上千次ajax请求 ,加了节流,便使得浏览器资源不会被无意义的消耗
结语
因为本人水平有限,如果有错漏的地方,还请看官多多指正
本文作者胡志武,写于2019/6/03,如果要转载,请注明出处,
如果觉得写的不错, 请点个赞吧