美文网首页
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