手写js防抖和节流方法

//防抖函数
// 防抖的概念
// 短时间内大量触发同一事件,只会执行一次函数,实现原理为设置一个定时器,约定在xx毫秒后再触发事件处理,每次触发事件都会重新设置计时器,直到xx毫秒内无第二次操作,
// 防抖常用于搜索框/滚动条/按钮点击 的监听事件处理,如果不做防抖,每输入一个字/滚动屏幕,都会触发事件处理,造成性能浪费
/**
 * func => 执行的函数体
 * wait => 等待的时间
 * immediate => 是否立即执行
 */
function debounce(func, wait, immediate) {
    //timeout => 控制间隔保存计时器的变量
    //result => 执行函数如果有返回值 最后给它 return 出去
    let timeout, result;
    //防抖函数主体
    let debounced = function () {
        //debounce(doSomeing,300);
        let context = this; //当前执行的方法的 this ,这里是 上面绑定事件的 dom
        let args = arguments; //当前执行方法里doSomeing 的 arguments
        if (timeout) clearTimeout(timeout); //如果还在运动中 清除上一次的计时器

        if (immediate) { //立即执行
            let callNow = !timeout; //默认立即执行 默认值 true
            // timeout = setTimeout 时 = true; 在等待时间后 timeout 等于null ;用户控制 callNow 变量
            timeout = setTimeout(() => {
                timeout = null;
            }, wait);

            //如果 callNow = true 执行
            if (callNow) result = func.apply(context, args); //改变执行函数内部this指向 ,并传入arguments

        } else { //非立即执行 事件结束后 等待时间 后执行
            timeout = setTimeout(function () {
                result = func.apply(context, args); //改变执行函数内部this指向 ,并传入arguments
            }, wait);
        }
        return result;
    }
    //防抖函数的取消方法
    debounced.cancel = function () {
        clearTimeout(timeout);
        timeout = null;
    }
    return debounced;
}

// 
// 节流:
// 防抖是延迟执行,而节流是间隔执行,函数节流即每隔一段时间就执行一次,实现原理为设置一个定时器,约定xx毫秒后执行事件,如果时间到了,那么执行函数并重置定时器,
// 和防抖的区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器
// 应用场景 => DOM元素拖拽 射击游戏 计算鼠标距离 scroll滚动事件
/**
 * func => 绑定的方法
 * wait => 间隔的时间
 * {leading,trailing} 3中情况 不能同时为false
 * leading => true,trailing => false, 第一次会立即执行 最后一次不会调用
 * leading => false,trailing => true, 第一次不会立即执行 最后一次会调用
 * leading => true,trailing => true, 第一次会立即执行 最后一次会调用
 */
function throttle(func, wait, options) {
    let context, args, timeout, oldTime = 0;
    if (!options) options = {};
    let later = function () {
        oldTime = new Date().valueOf();
        timeout = null;
        func.apply(context, args);
    }
    return function () {
        conntext = this;
        args = arguments;
        let nowTime = new Date().valueOf();
        //第一次不会立即执行
        if (options.leading === false && !oldTime) {
            oldTime = newTime;
        }
        //判断第一次进来 会不会 立即执行
        if (nowTime - oldTime > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            func.apply(context, args);//间隔时间到了就可以执行
            oldTime = nowTime;
        }
        //判断最后一次 会不会 执行
        else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, wait);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值