Because I often forget to prevent shaking and throttle, so I write this article to deepen my memory and facilitate myself to read later.

Image stabilization

  • The principle of anti-shake: you may trigger the event, but I must execute it n seconds after the event is triggered. If you trigger the event within n seconds, I will execute it n seconds after the new event.
  • Anti – shake function is divided into non – immediate execution and immediate execution version.
  • The most common example: search
    • Not an immediate release
    If the event is triggered within n seconds, the function will wait n seconds
    function debounce(func, wait) {
        let timeout;
        return function () {
            // This and arguments are saved so that debounce eventually returns the function this pointing unchanged and still receives the event argument.
            let ctx = this;
            let args = arguments;
            if (timeout) clearTimeout(timeout);
            
            timeout = setTimeout((a)= >{ func.apply(ctx, args); }, wait); }}Copy the code
    • Immediate execution version
    // Execute now is the effect that the function will execute immediately after the event is raised, and then the function will continue to execute after the event is not raised for n seconds
    function debounce(func, wait) {
        let timeout;
        return function () {
            let ctx = this;
            let args = argument;
            
            if (timeout) clearTimeout(timeout);
            letcallNow = ! timeout; timeout = setTimeout((a)= > {
                timeout = null;
            }, wait)
            
            if(callNow) func.apply(ctx, args); }}Copy the code

In fact, we can combine the two versions to make the function more complete

function debounce(func, wait, immediate) {
    let timeout;
    return function () {
        let ctx = this;
        let args = arguments;
        
        if (timeout) clearTimeout(timeout);
        if (immediate) {
            // If yes, no further action is required
            letcallNow = ! timeout; timeout = setTimeout((a)= > {
                timeout = null;
            }, wait)
            if (callNow) func.apply(ctx, args);
        } else {
            timeout = setTimeout(function() {
                func.apply(ctx, args)
            }, wait)
        }
    }
}
Copy the code

The throttle

  • How throttling works: If you keep firing events, only one event will be executed every once in a while
  • The effect varies depending on whether it is executed the first time and whether it is executed after the end.
  • There are two main implementation methods, one is to use event stamps, the other is to set timers
// Use event stamps
function throttle(func, wait) {
    let ctx;
    let args;
    let previous = 0;
    return function () {
        let now = +new Date(a); ctx =this;
        args = arguments;
        if(now - previous > wait) { func.apply(ctx, args); previous = now; }}}Copy the code
// Use timer
function throttle(func, wait) {
    let ctx, args;
    let timeout;
    let previous = 0;
    
    return function () {
        ctx = this;
        args = arguments;
        if(! timeout) { timeout = setTimeout(function() {
                timeout = null;
                func.apply(ctx, args);
            }, wait)
        }
    }
}
Copy the code

Compare the two methods. 1. The first event is executed immediately, and the second event is executed for the first time n seconds later. After the first event stops firing, there is no way to execute the event again. After the second event stops firing, the event will still be executed again

// Combine the advantages of the above two to combine the code
function throttle(func, wait) {
    let timeout, ctx, args, result;
    let previous = 0;
    
    let after = function() {
        previous = +new Date(a); tmeout =null;
        func.apply(ctx, args);
    }
    let throttled = function() {
        let now = +new Date(a);// The time remaining for the next func trigger
        let remaining = wait - (now - previous);
        ctx = this;
        args = arguments;
        // If there is no time left or you change the system time
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            previous = now;
            func.applyg(ctx, args);
        } else if (!timeout) {
            timeout = setTimeout(later, remaining);
        }
    };
    return throttled;
}

Copy the code

Thanks for referencing github.com/mqyqingfeng… Github.com/mqyqingfeng…