高级技巧之 节流&防抖

我们一般在监听input事件、scroll事件或者resize事件时,会有每次更改都触发的操作。每次操作都触发本质上说肯定是没问题的,但在于是否需要每次更改都去执行函数体?

就拿scroll事件来说,如果我们在频繁执行scroll的时候减少触发次数会不会有影响?

input事件每次更改都去服务器请求搜索的返回结果,所以每次触发都会请求一次,我们如果让input事件后延迟去执行,甚至等待用户的所有input事件后只执行一次搜索会不会更好?

 

这也就有了很多的优化方法:

函数节流

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数 节流会稀释函数的执行频率

// 时间戳法
function $throttle(fn, wait) {
    // 记录上次执行的时间,否则为0
    let prevTime = 0
    return function () {
        let nowDate = Date.now()
        // 判断此时的时间是否已经超过了上次的执行时间
        if (nowDate - prevTime > wait) {
            // 执行函数体
            fn.apply(this, arguments)
            // 赋值下次时间
            prevTime = nowDate
        }
    }
}


// 定时器法
function $throttle(fn, wait) {
    // 初始定时器
    let timer = null
    return function (...arg) {
        // 如果上次定时器已经被执行过,才进入
        if (!timer) {
            timer = setTimeout(() => {
                fn.apply(this, arg)
                // 执行后函数体后再把定时器清空
                timer = null
            }, wait)
        }
    }
}

// 应用:
let num = 0
window.addEventListener('scroll', $throttle(function () {
    console.log(num++)
}, 200))

函数防抖

触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

function $debounce (fn, wait) {
    let timer = null
    return (...arg) => {
        // 如果存在定时器则清空
        if (timer) clearTimeout(timer)
        // 重新设置定时器执行
        timer = setTimeout(() => {
            fn.apply(fn, arg)
        }, wait)
    }
}

// 应用:
let num = 0
window.addEventListener('scroll', $debounce(function () {
     console.log(num++)
}, 200))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值