一、是什么
防抖(debounce)
n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
特点
- 当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间(非常短的时间);
- 当事件密集触发时,函数的触发会被频繁的推迟;
- 只有等待了一段时间也没有事件触发,才会真正的执行响应函数;
防抖应用场景
(防抖在连续的事件,只需触发一次回调)
- 输入框中频繁的输入内容,搜索或者提交信息;
- 频繁的点击按钮,触发某个事件;
- 监听浏览器滚动事件,完成某些特定操作;
- 用户缩放浏览器的resize事件;
- 手机号、邮箱验证输入检测
节流(throttle)
n 秒内只运行一次,若在 n 秒内重复触发,只有一次执行
特点
- 当事件触发时,会执行这个事件的响应函数;
- 如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数;
- 不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的;
节流应用场景
(节流在间隔一段时间执行一次回调)
- 游戏中的一些设计–王者荣耀 英雄的普攻;
- 监听页面的滚动事件;
- 鼠标移动事件;
- 用户频繁点击按钮操作;
二、实现方式
防抖的实现方式
<input type="text" id="input">
<script src="./debounce.js"></script>
<script>
let input1 = 0
const handle = debounce(function(e){
console.log(`发送了第${++input1}次网络请求`,this,e);
},2000)
/* 防抖处理-----当输入内容非常的快 不进行触发 当每次输入内容间隔
2秒的时候进行触发
*/
const inp = document.getElementById("input").oninput = handle
</script>
// debounce.js
function debounce(fn,time){
let timer
return function(e){
// 设置新的之前把老的给清除
if(timer) clearInterval(timer)
timer=setTimeout(()=>{
// 用apply来改变this指向, 传递e是第二个参数是数组
fn.apply(this,[e])
},time)
}
}
执行的效果:
节流的实现方式
<input type="text">
<!--html标签-->
<script>
const inputEl = document.querySelector("input")
let counter = 0
const inputChange = function (event) {
console.log(`发送了第${++counter}次网络请求`, this, event)
}
// 节流处理
inputEl.oninput = throttle(inputChange, 2000)//当用户不断触发事件按照2秒的频率执行
function throttle(fn, interval) {
// 1. 记录上一次的开始时间
let lastTime = 0
return function (e) {
// 2.1.获取当前事件触发时的时间
const nowTime = new Date().getTime()
// 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数
const remainTime = interval - (nowTime - lastTime)
if(remainTime<=0){
// 2.3真正触发函数
fn() //做出响应
// 2.4保留上次触发的时间
lastTime = nowTime //更新最后一次执行的时间
}
}
}
</script>
执行的效果:
三、两者的区别:
相同点
- 都可以通过使用 setTimeout 实现
- 目的都是,降低回调执行频率。节省计算资源
不同点
- 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和
setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能 - 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次
例子:
都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次。