防抖(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>
实现。防抖我感觉还是比拟好了解的,下一篇说节流更绕一点。