函数节流与防抖

函数防抖

事件被触发后,在一定时间内再次触发,则以后一次触发为标准重新计算时间,直到这段时间内没有二次触发,才执行。

1、无防抖代码

//html代码
<input id="unDebounce">


//script代码
//模拟一段ajax请求
function ajax(content) {
  console.log('ajax request ' + content)
}

let inputa = document.getElementById('unDebounce')

inputa.addEventListener('keyup', function (e) {
    ajax(e.target.value)
})

没有防抖的情况下,输入框每输入一个单词,就会请求一次,浪费时间,效率低

打印结果如下:

 

 2、加入防抖函数

//html代码
<input id="debounce"/>

//script代码
//模拟一段ajax请求
function ajax(content) {
  console.log('ajax request ' + content)
}

function debounce(fun, delay) {
    return function (args) {
        let that = this
        let _args = args
        clearTimeout(fun.id)
        fun.id = setTimeout(function () {
            fun.call(that, _args)
        }, delay)
    }
}
    
let inputb = document.getElementById('debounce')

let debounceAjax = debounce(ajax, 500)

inputb.addEventListener('keyup', function (e) {
        debounceAjax(e.target.value)
})

加入防抖后,当你在输入框频繁输入时, 并不会连续发送请求。

只有当你在指定间隔时间内没有输入时,才会执行函数。也就是在keyup触发一定时间内没有再次触发,就会发送请求。

打印结果如下:

 函数节流

 在一段时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有第一次生效。

例1:频繁点击事件触发

不断点击页面,一段时间内只触发一次

function throttle(fn, delay) {
    var timer;
    return function () {
        var _this = this;
        var args = arguments;
        if (timer) {
            return
        }
        timer = setTimeout(function () {
            fn.apply(_this, args);
            timer = null;
        }, delay)
    }
}
function testThrottle(e, content) {
    console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 1000); // 节流函数
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // 给节流函数传参
}

 可看到,这段代码中清除定时器的时间与防抖不同。

防抖在执行时会先清除定时器,因为在规定时间内二次触发后会以后一次触发为标准重新计时。

节流则是判断是否有定时器,没有定时器就创建定时器执行,有定时器就用return阻止执行,直到前一次的执行完成,清除定时器,进行下一次的执行。这样就能在规定时间内只执行一次,规定时间内的其他触发无效。

例2: 时间戳实现节流函数

function throttle(fn,delay){
    var previous = 0;
    // 使用闭包返回一个函数并且用到闭包函数外面变量previous
    return function(){
        var _this = this;
        var args = arguments;
        var now = new Date();
        if(now - previous > delay){
            fn.apply(_this,args);
            previous = now;
        }
    }
}

function testThrottle(e,content){
    console.log(e,content);
}
var testThrottleFn = throttle(testThrottle,1000);
document.onmousemove = function(e){
    testThrottleFn(e,'throttle')
}

 原理:与前一次触发时间相比,如果时间差大于了延迟时间则触发。

运用场景 

debounce

  • search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
  • window触发resize时,不断调整浏览器窗口大小会不断触发事件,让防抖来让其触发一次

throttle

  • 鼠标不断的点击事件,mousedown(单位时间只触发一次)
  • 监听滚动事件,比如是否滑到底部自然加载更多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值