防抖、节流

防抖函数手写

当事件被触发时,设定一个定时器,若期间又被触发,则重新设定周期,直到周期结束

        //需求:监听浏览器滚动事件,返回当前滚条与顶部的距离

        //需求实现(未处理版)
        function watchScroll() {
            let scrollTop = document.body.scrollTop || document.documentElement.scrollTop
            console.log(scrollTop)
        }
        window.onscroll = watchScroll

        //需求实现(debounce处理版)
        //如果不做处理,在拖动滚动条时这个函数触发的频率会很高,为了不浪费浏览器性能,这里可以用上防抖函数
        /**
         * @param fn:需要防抖处理的函数,delay:防抖设置的间隔
         * @return function
         */
        function debounce(fn, delay) {
            let timer = null
            //这里用到了闭包,每次onscroll触发都会调用下一行返回的匿名函数,所以timer=null只会执行一次,并且timer会一直保留到闭包函数销毁为止      
            return function () {
                if (timer) {
                    clearTimeout(timer)
                    timer = setTimeout(fn, delay)
                } else {
                    timer = setTimeout(fn, delay)
                }
            }
        }
        function showTop() {
            let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
            console.log(scrollTop);
        }
        window.onscroll = debounce(showTop, 1000)
        //经过处理,滚动条停止滚动1秒以后,才会打印出滚动条位置

节流函数手写

当事件被触发时,在一定时间内只有第一次触发有效,若期间又被触发则无效,直到周期结束

阀门版
  /**
   * @param fn:需要节流处理的函数,delay:节流设置的间隔
   * @return function
   */
        function throttle2(fn, delay) {
            let working = false
            return function () {
                if (working) {
                    console.log("阀门未开")
                } else {
                    working = true
                    fn()
                    setTimeout(function () {
                        // fn()
                        working = false
                    }, delay)
                }
            }
        }
时间戳版
        function throttle(fn, delay) {
            let last = 0
            return function () {
                let now = Date.now()
                if (now > last + delay) {
                    fn()
                    // setTimeout(function () {
                    //     fn()
                    // }, delay)
                    last = now
                }
                else {
                    console.log("距离上次调用的时间差不满足要求哦")
                }
            }
        }

一般直接引用lodash防抖节流函数即可

原文地址:https://www.cnblogs.com/chyshy/p/13608443.html