防抖节流基本原理及实现

1、防抖:防抖是指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。(就是在触发某个事件后,在下一次触发之前,中间的间隔时间如果超过设置的时间才会发送请求,一直触发就不会发送请求)
实现代码如下:

// func代表一个函数,里面可能会频繁发生回调或ajax请求,delay表示隔多少秒触发才触发,immediate表示是否立即执行,可传true或false,默认false
function debounce(func,delay,immediate) {
    // result表示返回值
    let timeout,result

    let debounced = function () {
        // 存储触发当前事件的this
        let _this = this
        // 存储event对象
        let args = arguments
        clearTimeout(timeout)
        // 判断是否立即执行,如果不传默认不立即执行
        if (immediate){
            // 立即执行
            let callNow = !timeout
            timeout = setTimeout(()=>{
                timeout = null
            },delay)
            if (callNow) result = func.apply(_this,args)
        } else{
            timeout = setTimeout(function () {
                func.apply(_this,args)
            },delay)
        }
        return result
    }
    debounced.cancel=function () {
        clearTimeout(timeout)
        timeout = null
    }
    return debounced
}

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

2、节流:节流是指如果持续触发某个事件,则每隔n秒执行一次。
实现代码如下:

// func代表可能会频繁发生回调或ajax请求的函数,delay表示等待时间,options为一个对象,leading =true时代表第一次立即执行,training = true 表示最后一次也会被执行
function throttle(func, delay,options) {
    // 使用定时器和时间戳完成的第三版(第一次会触发,最后一次会触发)
    let context,args,timeout;
    // 之前的时间戳
    let oldTime = 0
    if (!options) options={}
    let later = function () {
        oldTime = new Date().valueOf()
        timeout = null
        func.apply(context,args)
    }
    return function () {
        context = this
        args = arguments

        // 获取当前时间戳
        let now = new Date().valueOf()

        // 判断第一次是否执行
        if (options.leading === false){
            // 不执行
            oldTime = now
        }

        // 第一次会触发
        if (now-oldTime > delay){
            if (timeout){
                // 清空定时器
                clearTimeout(timeout)
                timeout = null
            }
            // 立即执行
            func.apply(context,args)
            // 每隔delay秒执行一次
            oldTime = now
        }else if (!timeout && options.trailing!==false){
            timeout = setTimeout(later,delay)
        }
    }
}

主要应用场景:
a、DOM元素的拖拽功能实现
b、射击游戏类
c、计算鼠标移动的距离
d、监听scroll事件

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值