概念
所谓函数的防抖和函数的节流,是一种优化程序性能的技术。主要应用于事件处理程序中
什么情况下需要使用防抖和节流?
在元素触发一些事件,并且有可能频繁执行事件处理程序的时候。
如:onscroll,onkeyup,oninput,onmousemove等需要频繁执行事件处理程序的事件,事件的高频触发,事件处理程序频繁无限的执行,给浏览器造成了很大的压力,用户体验也很不好。特别是在一些事件触发后,如果需要向后台进行一些异步请求,高频的请求,会对服务器造成很大压力,大大消耗请求资源。因此,函数的防抖和函数的节流,可以很好的处理以上问题
我们不难理解高频触发事件的现象:
<input type="text" id="output"/>
<script type="text/javascript">
var output = document.getElementById("output");
output.addEventListener("input",function(){
console.log(this.value);
})
</script>
函数防抖:debounce
- 原理:简单来说就是将频繁执行的事件处理程序,通过处理,单位时间内保证只执行一次,以此达到降低事件触发频率的目的。
- 应用场景:比如懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费资源;另外还有做商品预览图的放大镜效果时,不必每次鼠标移动都计算位置。
<input type="text" id="output"/>
<script type="text/javascript">
var output = document.getElementById("output");
//函数节流
/*
* fn:执行的程序
* ms:执行程序的单位时间
*/
function throttle(fn,ms){
//单位时间的起始时间戳(上一次触发事件的时间)。
var prevTime = Date.now();
var timer = null;
return function(){//以事件处理程序存在
var nowTime = Date.now();//当前触发事件的时间戳。
//如果当前事件触发的时间与上一次触发事件的时间间隔不超过单位时间ms,则不需要执行程序,反之执行一次,这样就保证了ms单位时间段内只调用一次事件处理函数
if(nowTime - prevTime >= ms){
//执行fn程序,并改变fn上下文为当前事件源。
fn.call(this);
prevTime = nowTime;//修改起始时间戳为当前时间戳。
}
}
}
function fn(){
//这里的this为window,通过节流处理后this指向事件源。
console.log(this.value,new Date().getSeconds());
}
总结:
函数防抖:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在ms时间后触发函数,如果在ms时间内再次触发的话,就会取消之前的计时器并重新设置。这样一来,只有最后一次触发的事件才会真正的执行需要执行的程序。
函数节流:使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。
区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数