防抖(debounce)与节流(throttle)

防抖函数(debounce)

短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。

应用场景:
  1. search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
  2. window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
分类:
  1. 立即执行版

    立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。

function debounce(fn,wait = 500){
    let timer = null;
    let arg = arguments;
    let flag = true;
    return function(){
        clearTimeout(timer);
        if(flag){
            fn.apply(this,arg)
            flag = false
        }
        timer = setTimeout(()=>flag = true,wait)
    }
}

function spake(){
    console.log('防抖成功')
}

window.onmousemove = debounce(spake,3000)
  1. 非立即执行版

    非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

// 非立即执行版
function debounce(fn,wait = 500){
    let timer = null;
    let arg = arguments;
    return function(){
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this,arg)
        }, wait);
    }
}

function spake(){
    console.log('防抖成功')
}
let a = document.getElementById('a');
a.addEventListener('input',debounce(spake,1000))
整合版
/* 
   * @param fn 目标函数
   * @param wait 延迟执行毫秒数
   * @param isImmediate true-立即执行;false-非立即执行
*/
function debounce(fn, wait, isImmediate = false) {
    let timer = null;
    let arg = arguments;
    let flag = true;
    if (isImmediate) {
        return function () {
            clearTimeout(timer);
            if (flag) {
                fn.apply(this, arg)
                flag = false
            }
            timer = setTimeout(() => flag = true, wait)
        }
    }
    return function(){
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this,arg)
        }, wait);
    }
}

function spake() {
    console.log('防抖成功')
}

window.onmousemove = debounce(spake, 1000,true)

节流(throttle)

一个时间在n秒钟被多次触发,但是绑定的函数在期间只会执行一次(及稀释函数的执行频率)

应用场景:
  1. 鼠标不断点击触发,mousedown(单位时间内只触发一次)
  2. 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
分类:
  1. 时间戳版

    在持续触发事件的过程中,函数会立即执行,并且每 1s 执行一次。

    function throttle(fn, wait = 500) {
        let timer = 0;
        return function () {
            let arg = arguments;
            let now = Date.now();
            if (now - timer >= wait) {
                fn.apply(this,arg)
                timer = now
            }
        }
    }
    function spake() {
        console.log('节流成功')
    }
    window.onmousemove = throttle(spake,1000)
  1. 定时器版

    在持续触发事件的过程中,函数不会立即执行,并且每 1s 执行一次,在停止触发事件后,函数还会再执行一次。

    function throttle(fn,wait=500){
        let timer;
        return function(){
            let arg = arguments;
            if(!timer){
                timer = setTimeout(()=>{
                    timer = null;
                    fn.apply(this,arg)
                },wait)
            }
        }
    }
    function spake() {
        console.log('节流成功')
    }
    window.onmousemove = throttle(spake,1000)
两者区别在于时间戳版的在时间段开始时触发,而定时器版在时间段结束时触发
整合版
    /*
        * @param fn 函数
        * @param wait 延迟执行毫秒数
        * @param type 1-时间戳版,2-定时器版 默认为1
    */

    function throttle(fn,wait=500,type=1){
        if(type === 1){
            var pre = 0;
        }else if(type === 2){
            var timer;
        }
        return function(){
            let arg = arguments;
            if(type === 1){
                let now = Date.now();
                if(now - pre >= wait){
                    fn.apply(this,arg);
                    pre = now;
                }
            }
            else if(type === 2){
                if(!timer){
                    timer = setTimeout(()=>{
                        timer = null;
                        fn.apply(this,arg)
                    },wait)
                }
            }
        }
    }
    function spake() {
        console.log('节流成功')
    }
    window.onmousemove = throttle(spake,1000,2)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值