函数节流和函数防抖

函数节流和函数防抖

函数节流概念: 函数预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期

比如在做网页的时候有个需求,就是浏览器窗口改变的时候需要改一些页面元素大小,于是乎很自然的想到了window的resize事件

<script>

    var n = 0;
    function resizeHandler () {
        console.log(n++);
    }
    window.onresize = resizeHandler
</script>

效果随着窗口大小改变不停打印n的值

使用函数节流

<script>
    var n = 0;
    function resizeHandler () {
        console.log(n++)
    }
    function throttle (method, delay) {
        var timer = null;
        return function () {
            var context = this;
            var args = arguments;
            clearTimeout(timer);
            timer = setTimeout(() => {
                method.apply(context, args)
            }, delay);
        }
    }
    window.onresize = throttle(resizeHandler, 500);//因为返回函数句柄,不用包装函数了
</script>

窗口大小改变,不断打印n的值,但不要一直打印,500ms内如果没有继续拖动,则打印值
对于函数节流,有如下几个场景:

  • 游戏中的刷新率
  • DOM元素拖拽
  • Canvas画笔功能

函数防抖:函数执行过一次后,在等待某时间段内不能再次执行;在等待时间内触发此函数,则重新计算等待时间

<script>
    var n = 0;
    function debounce (method, wait, flag) {
        var timer = null;
        var context, args, result, timestamp;
        var later = function () {
            var oDate = new Date();
            var last = oDate.getTime() - timestamp; // 计算第一次时间戳与当前时间戳的差值。
            if (last < wait && last >= 0 ) { // 在等待时间内触发此函数,重新计时。
                timer = setTimeout(later, wait - last);
            } else {
                timer = null;
                if (!flag) { // 限制flag 为true时,执行回调函数。
                    result = method.apply(context, args);
                    if (!timer) {
                        context = args = null
                    }
                }
            }
        }

        return function () {
            var oDate = new Date();
            var callNow = flag && !timer; // 代表第一次调用立即执行。

            timestamp = oDate.getTime(); // 记录下当前时间戳
            context = this;
            args = arguments;
            if (!timer) { // 第一次触发时,timer为空,进入此分支
                timer = setTimeout(later, wait);
            }
            if (callNow) { // 第一次触发且flag为true,进入此分支
                result = method.apply(context, args);
                context = args = null
            }
            return result;
        }
    }
    window.onscroll = debounce (function () {
        console.log(1)
    }, 500, false)
</script>

此次封装支持两种形式:
flag为true时,连续事件触发时,只会在第一次触发的时候执行回调。

flag为false时,连续事件触发时,只会在最后一次触发的时候执行回调。

对于函数防抖,有以下几种应用场景:

  • 给按钮加函数防抖防止表单多次提交。
  • 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
  • 判断scroll是否滑到底部,滚动事件+函数防抖
    总的来说,适合多次事件一次响应的情况

欢迎大家点赞和评论,如有不足之处请大神指出,刚入门,请多多指教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值