Why use anti-shake technology

In front-end development, there will be some frequent events triggered, such as window resize, Scroll mouseDown, Mousemove KeyUp, keyDown… To do this, let’s use sample code to see how events can be fired frequently:

<! DOCTYPE HTML > < HTML lang="en"> <head> <meta charset="UTF-8"> <title> Type ="text" placeholder=" placeholder "; <script> var search = document.getelementbyid ('search'); Function getUserAction() {console.log(' perform query ',+new Date()); }; search.addEventListener('keyup', getUserAction) </script> </body> </html>Copy the code

The renderings are as follows:

As soon as the content is entered, the getUserAction function is always executed! Because this example is so simple, the browser is fine with it, but what about complex callback functions or Ajax requests? Assuming 10 fires per second, each callback must be completed within 1000/10 = 10ms, or there will be a stutter. To solve this problem, we can use anti-shake

Principle of image stabilization

Execute the callback function n seconds after the event is triggered. If the event is retriggered within n seconds, the timer is reset. The result is to consolidate frequently triggered events into one and execute them last.

The first example

The code is as follows:

var search = document.getElementById('search');
function getUserAction(e) {
    console.log(e);
    console.log('Perform query operation', +new Date());
  };

function debounce(func, wait) {
    var timeout;
    return args= > {
      if(timeout) clearTimeout(timeout) timeout = setTimeout(func, wait); }}const debounceAjax = debounce(getUserAction, 1000)

subBtn.addEventListener('keyup', debounceAjax)
Copy the code

The method will be executed in 1 second after input. The method will be executed in 1 second after input. Click to see the effect:

Second example

Execute immediately There is a requirement that the mouse move event, move over the content, execute the function immediately.

According to this statement, we can write code:

function debounce(func, wait, immediate) {
    var timeout;
    return args= > {
        let context = this;
        if (timeout) clearTimeout(timeout) 
        if (immediate) {
            // If it has already been executed, it will not be executed
            letcallNow = ! timeout; timeout = setTimeout(function() {
                timeout = null;
            },wait) 
          if (callNow) func.call(context, args)
        } else {
            timeout = setTimeout((a)= > {
                func.call(context, args)
            },wait)
        }
    }
}
Copy the code

Debounce (getUserAction, 1000, true) Move the mouse over the content to execute the method immediately, repeat the move 1 second after the last move to execute the method and see the effect:

Improved function added to cancel the anti – shake function

function debounce(func, wait, immediate) {
    var timeout,result;
    var debounced =  function() {
      var context = this;
      var args = arguments;

      if (timeout) clearTimeout(timeout);
      if (immediate) {
        // If yes, no further action is required
        varcallNow = ! 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;
    }

    debounced.cancel = function() {
    	  clearTimeout(timeout);
    	  timeout = null;
    }

    return debounced;
  }
Copy the code

Execution code:

var setUseAction = debounce(getUserAction, 1000.true);
  container.onmousemove = function() {
    var res = setUseAction();
    console.log(res)
  }

  document.getElementById("button").addEventListener('click'.function() {
    setUseAction.cancel();
  })
Copy the code

Set the time interval to be larger than 10 seconds. Click “Cancel the anti-shake” and execute it immediately. See the effect:

Reference address: github.com/mqyqingfeng…