js之深入认识防抖和节流

在前端开发中遇到写频繁触发事件的事情,会引起一些性能上的问题;我们就需要用防抖节流进行处理,结合实际场景和防抖节流的原理,自行考虑要哪个。
以下就是频繁触发事件的一些操作:

  1. window 的 resize、scroll
  2. mousedown、mousemove
  3. keyup、keydown
  4. input输入框动态搜索数据

防抖 深入了解防抖

原理: 你尽管触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行,总之,就是要等你触发完事件 n 秒内不再触发事件,我才执行。

function debounce(func, wait, immediate) {

    var timeout, result;

    return function () {
        var context = this;//func.apply(context, args)改变this的指向,指回func对象,否则的话就会指向window。
        var args = arguments;//func.apply(context, args)把函数的参数也一起传过去,包括事件对象event,否则的话就会显示undefined

        if (timeout) clearTimeout(timeout);
        if (immediate) { //我不希望非要等到事件停止触发后才执行,我希望立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行。用immediate判断是否要立即执行。
            // 如果已经执行过,不再执行
            var callNow = !timeout;
            timeout = setTimeout(function(){
                timeout = null;
            }, wait)
            if (callNow) result = func.apply(context, args)
        }
        else {
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
        return result;//返回func的执行结果。
    }
}

节流 深入了解节流

原理:无论你频繁触发多少次,每隔n秒内,只执行一次事件。

根据首次是否执行以及结束后是否执行,效果有所不同,实现的方式也有所不同。
我们用 leading 代表首次是否执行,trailing 代表结束后是否再执行一次。

关于节流的实现,有两种主流的实现方式,第一种是使用时间戳,第二种是设置定时器

  • 第一种事件会立刻执行,第二种事件会在 n 秒后第一次执行
  • 第一种事件停止触发后没有办法再执行事件,第二种事件停止触发后依然会再执行一次事件
function throttle(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if (!options) options = {};//leading:false 表示禁用第一次执行;trailing: false 表示禁用停止触发后再执行一次;这两个参数不能同时设置

    var later = function() {
        previous = options.leading === false ? 0 : new Date().getTime();
        timeout = null;
        func.apply(context, args);
        if (!timeout) context = args = null;
    };

    var throttled = function() {
        var now = new Date().getTime();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.apply(context, args);
            if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining);
        }
    };
    return throttled;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值