防抖(debounce)和节流(throttle)

防抖(debounce):任务频繁触发情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。

节流(throttle):指定时间间隔内只会执行一次任务。
 防抖与节流的原理:使用setTimeout来存放将要执行的函数。其中函数节流就是利用标记符来控制本次执行完毕。函数防抖就是利用clearTimeout来清楚执行的函数。目的为了节约计算机资源,从而达到一个更好的运行效果。

一、防抖

 用户在输入框内容校验等操作时,如果事件处理函数的调用频率无限制,会加重浏览器的负担,导致用户体验会很不好,防抖和节流的方式减少调用频率,同时又不影响实际效果。

下面是一个防抖的小案例:

<button id="debounce">点我防抖</button>
    <script>
        window.onload = function () {
            //获取按钮并绑定事件
            var myDebounce = document.getElementById("debounce");
            myDebounce.addEventListener("click",debounce(sayDebounce));
        };
        //防抖功能函数,接受传参
        function debounce(fn){
            //创建一个标记用来存放定时器的返回值
            let timeout = null;
            return function(){
                //每次当用户点击、输入的时候,把前一个定时器消除
                clearTimeout(timeout);
                //创建一个新的setTimeout,这样能保证点击按钮后的间隔内,
                //如果用户还点击的话,就不会执行fn函数
                timeout = setTimeout(() => {
                    fn.call(this,arguments);
                },1000);
            };
        };
        //防抖事件的处理
        function sayDebounce(){
            // ...有些需要防抖的工作,在这里进行
            console.log("防抖成功~");
        }
    </script>

在触发点击事件后,如果用户再次点击了,我们会清空之前的定时器,重新生成一个定时器。意思就是:这件事儿需要等待,如果你反复催促,就重新计时。
 总结一下就是:第一次触发事件,一段时间内没有再次触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,再一次触发了事件,就会重新开始延时。

二、节流

 节流:指定时间间隔内只会执行一次任务。
节流的应用:
1、懒加载监听滚动条的位置,使用节流按照一定的频率进行获取。
2、点击提交按钮,只允许一定时间内点击一次。

    <button id="throttle">点我防抖</button>
    <script>
        window.onload = function () {
            //获取按钮并绑定事件
            var myThrottle = document.getElementById("throttle");
            myThrottle.addEventListener("click",throttle(sayThrottle));
        };
        //节流函数
        function throttle(fn){
            //通过闭包保存一个标记
            let canRun = true;
            return function(){
                //在函数开头判断标志是否为true,不为true则中断函数
                if(!canRun){
                    return;
                }
                //将canRun设置为false,防止执行之前再被执行
                canRun  = false;
                //定时器
                setTimeout(() => {
                    fn.call(this,arguments);
                    //执行完事件(例如调用完接口)之后,重新将这个标志设置为true
                    canRun  = true;
                },1000);
            };
        };
        //需要节流的事件
        function sayThrottle(){
            // ...有些需要防抖的工作,在这里进行
            console.log("节流成功~");
        }
    </script>
posted @ 2019-12-31 16:04  JudeYQ  阅读(1884)  评论(0编辑  收藏  举报