防抖是指连续触发的时候只会执行一次,停止触发 N 秒后才能继续执行,而节流是指如果你持续触发事件,每隔一段时间,只执行一次事件。像防止按钮多次点击就用防抖,像是监听滚动事件就用节流。
防抖场景
- 即时搜索,一个输入框,改变值后进行搜索,要用防抖,例如500ms,我输一个单词 word 后500ms内没有再输入的话,执行搜索,避免输一个句子搜索N遍(搜索框搜索输入。只需用户最后一次输入完,再发送请求)
- 手机号、邮箱验证输入检测
- 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流场景
- 节流还能用在刷新上,有的人猛点刷新,但为了服务器考虑,我们只在每一秒刷新一次,做节流,就算他一秒点100次我们也只刷新1次
- 滚动加载,加载更多或滚到底部监听
- 谷歌搜索框,搜索联想功能
- 高频点击提交,表单重复提交
区别
- 防抖只有停止操作后才执行1次
防抖1秒,我连续点按钮10秒,在11秒的时候,执行一次 - 节流是每隔固定时间执行一次
节流1秒,我连续点按钮10秒,每秒执行一次,共执行10次
<div id="box"></div>
<br>
<button id="btn">测试</button>
<script>
// 防抖
var timer;
box.onmousemove = function () {
clearTimeout(timer)
timer = setTimeout(function () {
console.log("1")
}, 1000);
}
//节流
var lastTime = 0;
btn.onclick = function () {
var nowTime = new Date().getTime();
if (nowTime - lastTime > 1000) {
console.log("2")
lastTime = nowTime;
}
}
</script>
封装防抖
var myApp=fangdou(add,1000)
box.onmousemove = event=>{
myApp(event.clientX,20)
}
function add(a, b) {
console.log(a + b)
}
function fangdou(fn, time) {
var timer;
return function () {
clearTimeout(timer)
var arg=arguments;
timer = setTimeout(function () {
fn.apply(this, arg)
}, time);
}
}