防抖(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>

实现。防抖我感觉还是比拟好了解的,下一篇说节流更绕一点。