防抖(Debounce)和节流(throttle)都是用来控制某个函数在一定时间内执行多少次的技巧,两者相似而又不同。
函数节流(throttle):是让一个函数无法在很短的时间间隔内连续调用,当上一次函数执行后过了规定的时间间隔,才能进行下一次该函数的调用。
函数去抖(debounce):让一个函数在一定间隔内没有被调用时,才开始执行被调用方法。
两个方法都是用来提升前端性能,减轻浏览器压力。
防抖:
我们拿最为常见的scroll事件做例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
div{
height: 3000px;
}
</style>
</head>
<body>
<div>
</div>
<script>
window.onload=function () {
window.onscroll=function () {
console.log(document.body.scrollTop || document.documentElement.scrollTop);
}
}
</script>
</body>
</html>
未作防抖处理之前,我们看看会发生什么
1.gif
我们滚动鼠标滚轮,短时间内触发多个事件,DOM操作是很耗费性能的,如果在监听中,做了一些DOM操作,那无疑会给浏览器造成大量性能损失。
进行处理后的代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
div{
height: 3000px;
}
</style>
</head>
<body>
<div>
</div>
<script>
window.onload=function () {
let timer;
window.onscroll=function () {
if(timer){
clearTimeout(timer);
}
timer=setTimeout(function () {
console.log(document.body.scrollTop || document.documentElement.scrollTop);
},200);
}
}
</script>
</body>
</html>
防抖效果如下
2.gif
对防抖函数进行封装
/**
*防抖函数封装
*@method debounce
*@param {function|element}method
*@param {number|element}delay
*@return {function|element}
*/
function debounce(method,delay){
let timer;
return function () {
if (timer){
clearTimeout(timer);
}
timer=setTimeout(function () {
let params=Array.prototype.slice.apply(arguments);
method.apply(this,params);
},delay)
}
}
window.onscroll=debounce(function () {
console.log(document.body.scrollTop || document.documentElement.scrollTop);
},200);
我认为防抖效果应该会应用在电商平台订单提交之中,不可能让用户疯狂点击提交订单。
节流:我们拿点击事件做例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>
点击
</button>
<script>
let btn=document.getElementsByTagName("button")[0];
btn.onclick=function () {
console.log(1);
}
</script>
</body>
</html>
未进行节流处理
3.gif
进行节流处理后
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button>
点击
</button>
<script>
let btn=document.getElementsByTagName("button")[0];
let flag=true;
btn.onclick=function () {
if (flag){
console.log(1);
flag=false;
setTimeout(function () {
flag=true;
},2000);
}
}
</script>
</body>
</html>
效果如下
4.gif
对节流函数进行封装
/**
* throttle
* @param method
* @param delay
* @return {Function}
*/
let flag=true;
function throttle(method,delay){
return function () {
if (flag){
let params=Array.prototype.slice.apply(arguments);
method.apply(this,params);
flag=false;
setTimeout(function () {
flag=true;
},delay)
}
}
}
节流函数的使用还是很常见的,比如无缝轮播图的换页点击,不能让用户一直点击按键,至少应当等此页翻页完成。
ps:最近用支付宝里面的饿了么点外卖,由于等了很久没来,连续多次点了催单按钮,然后“奇怪”的事情就发生了,我停止点击后,每隔一秒就出现已催单的提示,就这样持续了接近半分钟,我感觉这个现象应该和防抖和节流有关。
网友评论