conan1992 / blog

记录下知识点..
3 stars 0 forks source link

防抖函数 #12

Open conan1992 opened 4 years ago

conan1992 commented 4 years ago

防抖

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

实现

function debounce(fn, timeout){
    timeout = timeout || 200;
    var timer = null;
    return function(){
        clearTimeout(timer);
        timer = setTimeout(fn, timeout)
    }
}

完善-this指向

function debounce(fn, timeout){
    timeout = timeout || 200;
    var timer = null;
    return function(){
        clearTimeout(timer);
        timer = setTimeout(fn.bind(this), timeout)
    }
}

完善-参数传递

function debounce(fn, timeout){
    timeout = timeout || 200;
    var timer = null;

    return function(){
        var context = this;
        var args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function(){
            fn.apply(context, args)
        }, timeout)
    }
}

需求--立即执行

事件触发后立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行。

function debounce(fn, timeout, immediate){
    timeout = timeout || 200;
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        clearTimeout(timer);
        if(immediate){
            var callNow = !timer;
            if(callNow){
                fn.apply(context, args)
            }
            timer = setTimeout(function(){
                timer = null;
            }, timeout)
        }else{

            timer = setTimeout(function(){
                fn.apply(context, args)
            }, timeout)
        }

    }
} 

返回值

function debounce(fn, timeout, immediate){
    timeout = timeout || 200;
    var timer = null;
    var result;
    return function(){
        var context = this;
        var args = arguments;
        clearTimeout(timer);
        if(immediate){
            var callNow = !timer;
            if(callNow){
                result = fn.apply(context, args)
            }
            timer = setTimeout(function(){
                timer = null;
            }, timeout)
        }else{

            timer = setTimeout(function(){
                fn.apply(context, args)
            }, timeout)
        }
        return result;
    }
} 

取消

function debounce(fn, timeout, immediate){
    timeout = timeout || 200;
    var timer = null;
    var result;
    var debounced =  function(){
        var context = this;
        var args = arguments;
        clearTimeout(timer);
        if(immediate){
            var callNow = !timer;
            if(callNow){
                result = fn.apply(context, args)
            }
            timer = setTimeout(function(){
                timer = null;
            }, timeout)
        }else{

            timer = setTimeout(function(){
                fn.apply(context, args)
            }, timeout)
        }
        return result;
    }
    debounced.cancel = function(){
        clearTimeout(timer);
        timer = null;
    }
}