1、防抖:在一定时间内,只执行最后一次任务
在事件被触发的N秒后再执行任务(回调函数),如果在这N秒内又触发事件,则重新计算:
当事件触发时,相应的响应处理函数不会立即被触发,而是等待一定的时间;
当事件密集触发时,函数的触发会被频繁的推迟;
只有等待了一段时间也没有事件触发,才会真正执行响应处理函数
function debounce (callback, time){
// 定义一个定时器
var timer = null;
return function(...args){
if (timer) clearTimeout(timer) // 取消上一次的定时器
const that = this
// 延迟执行
timer = setTimeout(function(){
// 外部传入的真正需要执行的函数,改变this指向为执行函数的this,不然this会指向window
callback.apply(that, args)
}, time)
}
}
运用场景:输入框关键字检索、监听滚动事件、用户缩放浏览器resize事件等
<input type="text" id="searchInput">
<script>
document.getElementById('searchInput').oninput = debounce(function(e){
console.log('关键字搜索', e.target.value)
},200)
</script>
2、节流:在一定时间内,同个任务只会执行一次
在一定时间内,只能触发一次响应函数,如果事件频繁触发,只有一次生效
/*方法1*/
function throttle(callback, interval = 500){
// 记录上一次开始的事件
var lastTime = 0
return function(args){
// 获取当前事件触发时的时间
var nowTime = Date.now()
// 计算需要去触发函数的剩余时间
var remainTime = interval - ( nowTime - lastTime )
if (remainTime <= 0 ){
// 真正触发函数
callback(args)
// 保留上次触发的时间
lastTime = nowTime
}
}
}
/*方法2*/
function throttle (callback, interval){
// 是否可以执行标识
var flag = true
return function(...args){
// 若执行标识为false,不处理
if (!flag) return
flag = false
const that = this
// 延迟执行
setTimeout(function(){
// 外部传入的真正需要执行的函数,改变this指向为执行函数的this,不然this会指向window
callback.apply(that, args)
flag = true
}, interval)
}
}
vue 项目中也可以使用现成开源的包"throttle-debounce"