函数防抖(debounce):触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
函数节流(throttle):高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。
函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。
防抖Debounce情景
①有些场景事件触发的频率过高(mousemove onkeydown onkeyup onscroll)
②回调函数执行的频率过高也会有卡顿现象。 可以一段时间过后进行触发去除无用操作
防抖原理
一定在事件触发 n 秒后才执行,如果在一个事件触发的 n 秒内又触发了这个事件,以新的事件的时间为准,n 秒后才执行,等触发事件 n 秒内不再触发事件才执行。
官方解释:当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
演示:
<!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>
<input type="text"id="ipt"><button id="btn1">提交</button>
<script>
var ipt=document.getElementById("ipt");
var time=null;
// function ajax(){
// console.log(this.value);
// }
// ipt.oninput=function(){
// var ipt2=this;
// clearInterval(time);
// thime=setTimeout(function(){
// ajax.apply(ipt2);
// },1000);
// }
ipt.addEventListener('input',function(){
if(time!==null){
clearTimeout(time);
}
time=setTimeout(()=>{
console.log(this.value);
},1000)
})
</script>
</body>
</html>
节流Throttle情景
①图片懒加载
②ajax数据请求加载
节流原理
如果持续触发事件,每隔一段时间只执行一次函数。
官方解释:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
演示:
<!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>
<div id="div1">1</div><button id="btn1">点击</button>
<script>
var div1=document.getElementById("div1");
var btn1=document.getElementById("btn1");
function throttling (handle,wait){
var time=0;
return function(){
var nowtime=new Date().getTime();
if(nowtime-time>wait){
handle();
time=nowtime;
}
}
}
function computer(){
div1.innerHTML=parseInt(div1.innerHTML)+1;
}
btn1.onclick=throttling(computer,2000);
</script>
</body>
</html>
总结:
函数防抖:将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。
函数节流:使得一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行。
区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。