美文网首页
2019-06-03 节流函数-复习

2019-06-03 节流函数-复习

作者: Simon_s | 来源:发表于2019-06-03 14:57 被阅读0次

    节流:

    应用场景:监听滚动事件,比如是否滑到底部自动加  、重复点击按钮提交事件
    

    节流函数的作用是规定一个单位时间,在这个单位时间内最多只能触发一次函数执行,如果这个单位时间内多次触发函数,只能有一次生效。
    举例说明:小明的妈妈和小明约定好,如果小明在周考中取得满分,那么当月可以带他去游乐场玩,但是一个月最多只能去一次。
    这其实就是一个节流的例子,在一个月的时间内,去游乐场最多只能触发一次。即使这个时间周期内,小明取得多次满分

    节流函数实现方式

    1、利用时间戳实现

    function throttle (func, delay) {
        var lastTime = 0;
        function throttled() {
            var context = this;
            var args = arguments;
            var nowTime = Date.now();
            if(nowTime > lastTime + delay) {
                func.apply(context, args);
                lastTime = nowTime;
            }
        }
        //节流函数最终返回的是一个函数
        return throttled; 
    }
    

    2、定时器实现

    function throttle(func, delay) {
        var timeout = null;
        function throttled() {
            var context = this;
            var args = arguments;
            if(!timeout) {
                timeout = setTimeout(()=>{
                    func.apply(context, args);
                    clearTimeout(timeout);
                    timeout=null
                }, delay);
            }
        }
        return throttled;
    }
    

    注释:

    时间戳和定时器的方式都没有考虑最后一次执行的问题,比如有个按钮点击事件,设置的间隔时间是1S,在第0.5S,1.8S,2.2S点击,那么只有0.5S和1.8S的两次点击能够触发函数执行,而最后一次的2.2S会被忽略。

    3、组合实现,允许设置第一次或者最后一次是否触发函数执行

    function throttle (func, wait, options) {
        var timeout, context, args, result;
        var previous = 0;
        if (!options) options = {};
    
        var later = function () {
            previous = options.leading === false ? 0 : Date.now() || new Date().getTime();
            timeout = null;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        };
    
        var throttled = function () {
            var now = Date.now() || new Date().getTime();
            if (!previous && options.leading === false) previous = now;
            var remaining = wait - (now - previous);
            context = this;
            args = arguments;
            if (remaining <= 0 || remaining > wait) {
                if (timeout) {
                    clearTimeout(timeout);
                    timeout = null;
                }
                previous = now;
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            } else if (!timeout && options.trailing !== false) {
                // 判断是否设置了定时器和 trailing
                timeout = setTimeout(later, remaining);
            }
            return result;
        };
    
        throttled.cancel = function () {
            clearTimeout(timeout);
            previous = 0;
            timeout = context = args = null;
        };
    
        return throttled;
    }
    
    

    实现方式

    btn.onclick = throttle(handle, 1000, {leading:true, trailing: true});
    

    防抖:(debounce)

    触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
    

    实现思路:

    每次触发事件时都取消之前的延时调用方法
    
    function debounce(fn) {
          let timeout = null; // 创建一个标记用来存放定时器的返回值
          return function () {
            clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
            timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
              fn.apply(this, arguments);
            }, 500);
          };
        }
        function sayHi() {
          console.log('防抖成功');
        }
    
        var inp = document.getElementById('inp');
        inp.addEventListener('input', debounce(sayHi)); // 防抖
    

    相关文章

      网友评论

          本文标题:2019-06-03 节流函数-复习

          本文链接:https://www.haomeiwen.com/subject/wetcxctx.html