js防抖

15 篇文章 0 订阅

什么是函数防抖?

概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n秒内又触发了事件,则会重新计算函数延执行时间。

为什么需要函数防抖?

前端开发过程中,有一些事件,常见的例如,onresize,scroll,mousemove ,mousehover
等,会被频繁触发(短时间内多次触发),不做限制的话,有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,尤其是执行了操作DOM 的函数(浏览器操作 DOM是很耗费性能的),那不仅会浪费计算机资源,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。

除此之外,短时间内重复的 ajax 调用不仅会造成数据关系的混乱,还会造成网络拥塞,增加服务器压力。

怎么使用函数防抖解决上述问题

根据上面对问题的分析,我得到以下思路

函数防抖的要点,是需要一个 setTimeout 来辅助实现,延迟运行需要执行的代码。如果方法多次触发,则把上次记录的延迟执行代码用clearTimeout 清掉,重新开始计时。若计时期间事件没有被重新触发,等延迟时间计时完毕,则执行目标代码。

函数防抖的代码实现
根据以上分析,我们对 “函数防抖” 来进行简单的代码实现,如下:

// 将会包装事件的 sunFd函数
function sunFd(fn, de) {
  // 维护一个 time
  let time = null;

  return function() {
    // 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
    let context = this;
    let args = arguments;

    clearTimeout(time);
    time = setTimeout(function() {
      fn.apply(context, args);
    }, de);
  }
}
// 当用户滚动时被调用的函数
function fd() {
  console.log('滚动!');
}

// 在 sunFd 中包装我们的函数,过 2 秒触发一次
let elem = document.getElementById('container');
elem.addEventListener('scroll', sunFd(fd, 2000));

首先,我们为scroll事件绑定处理函数,这时sunFd函数会立即调用

每一次事件被触发,都会清除当前的 time然后重新设置超时调用。
这就会导致每一次高频事件都会取消前一次的超时调用,导致事件处理程序不能被触发

只有当高频事件停止,最后一次事件触发的超时调用才能在de时间后执行

更进一步,我们不希望非要等到事件停止触发后才执行,我希望立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行。
这里增加一个immediate参数来设置是否要立即执行:

function debouce(func,de,immediate){
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        if(timer) clearTimeout(time);
        if(immediate){
            //根据距离上次触发操作的时间是否到达de来决定是否要现在执行函数
            var doNow = !timer;
            //每一次都重新设置timer,就是要保证每一次执行的至少de秒后才可以执行
            timer = setTimeout(function(){
                timer = null;
            },de);
            //立即执行
            if(doNow){
                func.apply(context,args);
            }
        }else{
            timer = setTimeout(function(){
                func.apply(context,args);
            },de);
        }
    }
}

函数节流的使用场景

函数防抖一般用在什么情况之下呢?
一般用在,连续的事件只需触发一次回调的场合。
具体有:

  1. 搜索框搜索输入。只需用户最后一次输入完,再发送请求;
  2. 用户名、手机号、邮箱输入验证;
  3. 浏览器窗口大小改变后,只需窗口调整完后,再执行 resize 事件中的代码,防止重复渲染。

总结

函数防抖其实是分为 “立即执行版” 和 “非立即执行版” 的,根据字面意思就可以发现他们的差别,所谓立即执行版就是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 而 “非立即执行版” 指的是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值