函数的防抖和节流

函数的防抖和节流

防抖和节流

  • 防抖: 立即执行和非立即执行;执行一次;经常用于搜索框;
  • 节流: 时间戳 和定时器版; 控制每隔一段时间执行一次;稀释执行的频率; window.onscroll

函数的防抖

  • 所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,

则会重新计算函数执行时间。

<div id="box" style="width:100px;height:100px;background: red;text-align: center;
line-height: 100px;">0</div>
<script>
  // 所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,
  则会重新计算函数执行时间。

  //1非立即执行版:
  // 非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,
如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
  // let box = document.getElementById("box");
  // let num =1;
  // function add(a,b,c){
  //     //console.log(this);
  //     box.innerHTML =num++;
  // }
  // // 在n秒内就触发一次;
  // // 事件不会一直触发,当停下以后1s之后再触发这个函数;
  // function debounce(fn,wait){
  //     let timer;
  //     return function(){
  //         // 每次进到这个函数中,需要把上次定制的定时器任务给清除掉
  //         if(timer){
  //             clearTimeout(timer);
  //         }
  //         timer=setTimeout(()=>{
  //             fn.apply(this)// 通过apply修改了fn执行时里面的this指向,让它指向绑定那个元素
  //         },wait);
  //     }
  // }
  // box.οnmοusemοve=debounce(add,1000);

  //2 立即执行版:
  // 立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
  // let num = 1;
  // let content = document.getElementById('box');
  // function count() {
  //     content.innerHTML = num++;
  // };
  // content.onmousemove = debounce(count,1000);

  // function debounce(func, wait) {
  //     let timeout;
  //     return function () {
  //         let context = this;
  //         let args = arguments;

  //         if (timeout) clearTimeout(timeout);

  //         let callNow = !timeout;
  //         timeout = setTimeout(() => {
  //             timeout = null;
  //         }, wait)

  //         if (callNow) func.apply(context, args) 
  //     }
  // }


  // 双剑合璧版:
  /**
         * @desc 函数防抖
         * @param func 函数
         * @param wait 延迟执行毫秒数
         * @param immediate true 表立即执行,false 表非立即执行
         */
  // function debounce(func, wait, immediate) {
  //     let timeout;

  //     return function () {
  //         let context = this;
  //         let args = arguments;

  //         if (timeout) clearTimeout(timeout);
  //         if (immediate) {
  //             var callNow = !timeout;
  //             timeout = setTimeout(() => {
  //                 timeout = null;
  //             }, wait)
  //             if (callNow) func.apply(context, args)
  //         } else {
  //             timeout = setTimeout(function () {
  //                 func.apply(context, args)
  //             }, wait);
  //         }
  //     }
  // }

函数的节流

  • 节流(throttle)
    • 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
        // 节流(throttle)
        // 所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
        let num = 1;
        let content = document.getElementById('box');

        function count() {
            content.innerHTML = num++;
        };

        // 时间戳版:
        // 在持续触发事件的过程中,函数会立即执行,并且每 1s 执行一次。
        // function throttle(func, wait) {
        //     let previous = 0;
        //     return function () {
        //         let now = Date.now();
        //         let context = this;
        //         let args = arguments;
        //         if (now - previous > wait) {
        //             func.apply(context, args);
        //             previous = now;
        //         }
        //     }
        // }
        // content.onmousemove = throttle(count, 1000);

        // 定时器版:
        // 在持续触发事件的过程中,函数不会立即执行,并且每 1s 执行一次,在停止触发事件后,函数还会再执行一次。
        function throttle(func, wait) {
            let timeout;
            return function () {
                let context = this;
                let args = arguments;
                if (!timeout) {
                    timeout = setTimeout(() => {
                        timeout = null;
                        func.apply(context, args)
                    }, wait)
                }

            }
        }
        
        // 双剑合璧版:
        /**
         * @desc 函数节流
         * @param func 函数
         * @param wait 延迟执行毫秒数
         * @param type 1 表时间戳版,2 表定时器版
         */
        function throttle(func, wait, type) {
            if (type === 1) {
                var previous = 0;
            } else if (type === 2) {
                var timeout;
            }
            return function () {
                let context = this;
                let args = arguments;
                if (type === 1) {
                    let now = Date.now();

                    if (now - previous > wait) {
                        func.apply(context, args);
                        previous = now;
                    }
                } else if (type === 2) {
                    if (!timeout) {
                        timeout = setTimeout(() => {
                            timeout = null;
                            func.apply(context, args)
                        }, wait)
                    }
                }
            }
        }

函数防抖与节流(简约)

<body>
    <div id="box" style="width:100px;height:100px;background: red;text-align: center;line-height: 100px;">0</div>
    <script>
        //什么是防抖 节流 
        //你的项目中哪个地方中用到了防抖和节流

        //防抖
        //
        let box = document.getElementById("box");
        let num = 1;

        function add() {
            this.innerHTML = num++;
        }
        非立即执行
        function debounce(fn, time) {
            let timer;
            return function () {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    fn.call(this)
                }, time)
            }

        }
        box.onmousemove = debounce(add, 1000);

        立即执行
        立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
        function debounce(fn, time) {
            let timer;
            return function () {
                clearTimeout(timer)
                if (!timer) {
                    fn.call(this);
                }
                timer = setTimeout(() => {
                    timer = null;
                }, time)
            }
        }
        box.onmousemove = debounce(add, 1000);

        二合一
        function debounce(fn, time, immediate) {
            let timer;

            return function () {
                let context = this;
                let args = arguments;

                if (timer) clearTimeout(timer);
                if (immediate) {
                    if (!timer) {
                        fn.call(this);
                    }
                    timer = setTimeout(() => {
                        timer = null;
                    }, time)
                } else {
                    timer = setTimeout(() => {
                        fn.call(this)
                    }, time)
                }
            }
        }
        box.onmousemove = debounce(add, 1000, false); // true 表立即执行

        节流
        onmousemove onscroll onreset//可视窗口变化触发事件

        时间戳
        所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
        function throttle(fn, time) {
            let pervious = 0;
            return function () {
                let now = Date.now();
                if (now - pervious > time) {
                    fn.call(this);
                    pervious = now;
                }
            }
        }
        box.onmousemove = throttle(add, 2000); // true 表立即执行

        定时器版
        在持续触发事件的过程中,函数不会立即执行,并且每 1s 执行一次,在停止触发事件后,函数还会再执行一次  
        function throttle(fn, time) {
            let timer;
            return function () {
                if (!timer) {
                    timer = setTimeout(() => {
                        timer = null;
                        fn.call(this)
                    }, time)
                }

            }
        }
        box.onmousemove = throttle(add, 2000); // true 表立即执行

        //二合一
        function throttle(fn, time, type) {
            if (type === 1) {
                var pervious = 0;

            } else if (type === 2) {
                var timer;

            }
            return function () {
                if (type === 1) {
                    let now = Date.now();
                    if (now - pervious > time) {
                        fn.call(this);
                        pervious = now;
                    }
                } else if (type === 2) {
                    if (!timer) {
                        timer = setTimeout(() => {
                            timer = null;
                            fn.call(this)
                        }, time)
                    }
                }

            }


        }
        box.onmousemove = throttle(add, 2000, 1); // true 表立即执行
    </script>
</body>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值