美文网首页
JS debounce(防抖) 和 throttle(节流)

JS debounce(防抖) 和 throttle(节流)

作者: Cherry丶小丸子 | 来源:发表于2021-04-14 11:09 被阅读0次

    防抖

    防抖,即如果短时间内大量触发同一事件,都会重置计时器,等到事件不触发了,再等待规定的时间,才会执行函数。
    * 规定时间内,只触发一次

    应用场景:
    scroll事件滚动触发
    搜索框输入查询
    表单验证
    按钮提交事件
    浏览器窗口缩放,resize事件

    function debounce(fn, delay = 500, immediate) {
        // 1、创建一个标记用来存放定时器的返回值
        let timeout = null;
        return function() {
            // 2、每次当用户点击(timeout 有定义)的时候,清除前一个定时器
            if (timeout) clearTimeout(timeout);
           
            // 3、创建一个新的 setTimeout,这样就能保证点击按钮后的 delay 间隔内,如果用户还点击了的话,就不会执行 fn 函数
            const [that, args] = [this, arguments];
            if(immediate){ // 立即执行
                let callNow = !timeout;
                timeout = setTimeout(() => {
                    timeout = null;
                }, delay);
                if (callNow) fn.apply(that, args);
            }else{ // 非立即执行
                timeout = setTimeout(() => {
                    fn.apply(that, args);
                }, delay);
            };
        };
    }
    // 调用:
    <a href="javascript:;" id="btn">防抖</a>
    let btn = document.getElementById('btn');
    btn.addEventListener('click', this.debounce(this.chenhf, 1000, false));
    

    节流

    节流,即在连续的操作中,无论进行了多长时间,只有某一次的操作后在指定的时间内没有再操作,这一次才被判定有效
    * 每隔一段时间 只 执行一次

    应用场景:
    dom元素的拖拽功能实现
    射击游戏
    计算鼠标移动的距离
    监听scroll滚动事件

    时间戳版:
    function throttle(fn, delay) {
        let previous = 0;
        return function() {
            const [that, args] = [this, arguments];
            let now = Date.now();
            if (now - previous > delay) {
                fn.apply(that, args);
                previous = now;
            }
        }
    }
    定时器版:
    
    function throttle(fn, delay) {
        let timeout = null;
        return function() {
            const [that, args] = [this, arguments];
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null;
                    fn.apply(that, args);
                }, delay);
            }
        }
    }
    合并:
    function throttle(fn, delay, type) {
        let previous,timeout;
        if(type === 1){ // 时间戳版
            previous = 0;
        }else if(type === 2){ // 定时器版
            timeout = null;
        }
        return function() {
            const [that, args] = [this, arguments];
            if(type === 1){ // 时间戳版
                let now = Date.now();
                if (now - previous > delay) {
                    fn.apply(that, args);
                    previous = now;
                }
            }else if(type === 2){ // 定时器版
                if (!timeout) {
                    timeout = setTimeout(() => {
                        timeout = null;
                        fn.apply(that, args)
                    }, delay)
                }
            }
        }
    }
    // 调用:
    <a href="javascript:;" id="btn">防抖</a>
    let btn = document.getElementById('btn');
    btn.addEventListener('click', this.throttle(this.chenhf, 1000, 1));
    

    相关文章

      网友评论

          本文标题:JS debounce(防抖) 和 throttle(节流)

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