防抖(debounce)指的是:事件连续不断触发,只响应最初一次。
理论的使用场景是:滚动、鼠标高频点击、窗口大小间断变动、input 输出等事件,会频繁触发响应函数,但咱们不须要这么频繁的响应。咱们感觉这一波高频事件实现后再做一次响应就行了。
因而防抖的具体过程是:事件触发后设置“缄默”定时器,并革除之前的定时器,“缄默”肯定工夫(不会太长)后,定时器到期并执行动作。
这篇文章的工夫线图片能够帮忙了解:js 防抖和节流
先不思考封装函数。针对 scoll 的防抖应该是这样:
<script>
document.addEventListener('DOMContentLoaded', function () {
var timer = null;
document.addEventListener('scroll', function () {// console.log('scolling');
clearTimeout(timer);
timer = setTimeout(function () {console.log('scrolled DEBOUNCE');
}, 1000);
});
});
</script>
页面加上大段文字或者 <br> 就能看出滚动防抖的成果了。(如果你的浏览器不反对监听 document 的 scoll,试试改成 window 或 document.body)
代码中输入“scrolling”那行被正文掉了,如果没正文,就会一直地输入“scrolling”;相比之下,防抖的输入“scrolled DEBOUNCE”只会在滚动进行 1000ms 后输入一次。
接下来是封装函数。一开始我想到的封装是这样子的:
<script>
document.addEventListener('DOMContentLoaded', function () {function debounce(dom, eventType, wait, handler) {
var timer = null;
dom.addEventListener(eventType, function () {clearTimeout(timer);
timer = setTimeout(function () {handler();
}, wait);
});
}
debounce(document, 'scroll', 1000, function () {console.log('you stopped scrolling 1000ms ago');
});
});
</script>
模式太 low 了。看了他人的封装模式,针对响应动作封装就好。参数就是对于做什么动作、提早多久才做,尽量不扭转原有的监听语句模式。改成这样:
<script>
document.addEventListener('DOMContentLoaded', function () {function debounce(handler, delay) {
var timer = null;
return function () {clearTimeout(timer);
timer = setTimeout(function () {handler();
}, delay);
}
}
document.addEventListener('scroll', debounce(function () {console.log('you stopped scrolling 1000ms ago');
}, 500));
});
</script>
实现。防抖我感觉还是比拟好了解的,下一篇说节流更绕一点。