首先,我们先看一下什么是防抖与节流以及其背景。我们在浏览一个网站时,比如我们在逛淘宝,我们在看商品时鼠标总是会移来移去的,在这个过程中,我们可能会触发许多的事件,例如光标移入移出事件,我们会在无意中触发多次。当这样的事件设置了很多时,我们快速的移动鼠标触发他们会发现我们只触发了一部分事件,并没有触发所有的光标移入移出事件,这是为什么?这是由于我们的移动速度太快,浏览器的引擎在解析js代码时没有反应过来就结束了(就是浏览器的卡顿现象)。那么如果我们缓慢移动鼠标,一定可以触发所有的事件。但是我们在逛这些网站时,哪会管它能不能反应的过来,所以我们就需要减少事件的触发来确保我们可以稳定触发我们需要的事件,防抖与节流就这样产生了。
我们分开来看这两个概念:
- 节流:在规定的间隔时间范围内不会重复触发回调,把频繁触发变为少量触发。
- 防抖:前面的所有的触发都被取消,最后一次执行在规定时间之后才会触发,也就是说如果连续快速的触发,只会执行一次。
为方便理解节流,我们先做一个计数器的demo:
<body>
<div>
<h1>我是计数器<span>0</span></h1>
<button>点击我加上1</button>
</div>
</body>
<script>
let span = document.querySelector('span');
let button = document.querySelector('button');
let count = 0;
button.onclick = function(){
count++;
span.innerHTML = count;
console.log("执行");
}
</script>
接着我们看效果:
无论我们的点击速度之间的时间间隔是多少,计数器都会立即响应。这时我们使用节流函数(注意:需要引入lodash函数库):
<body>
<div>
<h1>我是计数器<span>0</span></h1>
<button>点击我加上1</button>
</div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
<script>
let span = document.querySelector('span');
let button = document.querySelector('button');
let count = 0;
button.onclick = _.throttle(function(){
count++;
span.innerHTML = count;
console.log("执行");
},1000);
</script>
这次的计数器的事件触发就被规定了时间间隔,在规定的时间间隔内只会触发一次,也就是说,我们无论如何疯狂的点击按钮,它在1s内只会触发一次。这样就大大减少了事件的触发。
然后我们再理解一下防抖,先做一个demo:
<body>
<p>
请你输入搜索内容:<input type="text">
</p>
</body>
<script>
let input = document.querySelector('input');
input.oninput = function(){
console.log("执行");
}
</script>
我们来看这个demo:
它的事件是 oninput ,这个事件是只要输入框内容有变化就执行回调,所以我在输入框中输入 abcde 时,下面执行了5次回调。但在现实生活中,我们往往希望当用户全部输入完毕后再去发送请求,所以这时我们就要用到防抖函数了:
<body>
<p>
请你输入搜索内容:<input type="text">
</p>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
<script>
let input = document.querySelector('input');
input.oninput = _.debounce(function(){
console.log("执行");
},1000)
</script>
加了防抖函数后的效果:
可以看到这次我们将5个字母全部输入完后才执行,这个防抖的作用是可以设置一个时间间隔,在经过这个时间段之后,执行这个时间段内最后一次触发事件的回调,之前的事件触发都被取消。
最后我将这两个函数的官方文档放在这里方便大家参考: