防抖和节流函数 解析

防抖函数:两次触发事件间隔足够的时间才会被触发

var _ = {};
_.now = function () {
    return new Date().getTime()
};
/**防抖: func 执行的方法,wait 等待时间 ,immediate true表示立即执行(此处逻辑代码已经删除)**/
_.debounce = function (func, wait, immediate) {
    var timeout, args, context, timestamp, result;
    //这些变量和方法参数是所有执行事件的函数共享!!!	  
    var later = function () {
        //下面三行代码是核心。		   
        var last = _.now() - timestamp;
        console.log(last)
        //当事件再wait时间段内再次被触发timestamp就会被改变,setTimeOut中的last预期就小于wait.我们就需要等待wait - last剩余时间之后再执行	
        if (last < wait && last >= 0) {
            
            //timestamp被改变了,照成last不够wait,我们就需要等待wait - last剩余时间之后再执行	
            timeout = setTimeout(later, wait - last); 
        } else {
            timeout = null;//足够空闲时间,执行函数;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        }
    };
    return function () {
        /**触发事件返回闭包函数,可以操作func,wait,以及设置的几个全局变量和later方法**/
        context = this; //事件调用的话,this就是dom对象	    
        args = arguments; //事件调用的话,就是事件的e参数	
        timestamp = _.now(); //最后一次事件触发的时间戳。	
        if (!timeout) { //只有timeout没有初始化的时候,才会设置setTimeout。	  
            timeout = setTimeout(later, wait); //启动延迟执行,later内部会递归调用。	
        }
        return result;
    };
};
点我2
document.querySelector("#send2").addEventListener("click", _.debounce(function () { console.log("点击2"); }, 1000)); _.debounce(function () { console.log('hello debounce') }, 1500)

节流函数:一段时间内就算触发多次时间,也只会执行一次

_.throttle = function (func, wait, options) {
    var context, args, result;
    var timeout = null;
    var previous = 0;
    if (!options) options = {};
    var later = function () {
        previous = options.leading === false ? 0 : _.now();
        timeout = null;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
    };
    return function () {
        var now = _.now();
        if (!previous && options.leading === false) previous = now;//options.leading === false 禁用第一次
        var remaining = wait - (now - previous);//options.leading === false remain===wait;否则remain<0
        context = this;
        args = arguments;
        if (remaining <= 0) {//没有禁第一次;或者间隔时间大于wait了;
            if (timeout) {//timeout存在;不是第一次的情形了。
                clearTimeout(timeout);//清除timeout
                timeout = null;
            }
            previous = now;
            result = func.apply(context, args);//第一次立即执行;往后立即执行;
            if (!timeout)
                context = args = null;
        } else if (!timeout && options.trailing !== false) {//最后一次没有被禁;
            timeout = setTimeout(later, remaining);
        }
        return result;
    };
};

 

你可能感兴趣的:(防抖和节流函数 解析)