scenario

In a movie project, I want to save the current location of the dropdown in the list of movies, so that when you switch the page and switch back to the current movie list page, it will return to the first data of the movie. At this point, I don’t want to save the current position every time I swipe a little bit, I want to save it every once in a while, so that I can use anti-shake and throttling.

concept

To put it bluntly, anti – shake throttling is the use of timer to achieve our purpose

Image stabilization (debounce) :

The callback is executed n seconds after the event is triggered, and if it is triggered again within n seconds, the timer is reset.

A typical case is the input box search: n seconds after the end of the input to search the request, n seconds after the input of the content, then re-timing.Copy the code

The throttle (throttle) :

Specifies that only one function can be triggered in a unit of time. If multiple functions are triggered in a unit of time, only one function takes effect.

A typical example is the repeated mouse click trigger, which specifies that multiple clicks only work once in n seconds.Copy the code

usage

Image stabilization (debounce)

** Drop down list, save the current drop down position at intervals. 台湾国

Mounted hook we can implement our shock protection in mounted hook:

// let timer; Ref ="list" $el this.$refs.list.$el. AddEventListener (" Scroll ", E => {console.log("---->", e.target.scrolltop) // Do not use anti-shake if (timer) {// Clear timer clearTimeout(timer); } timer = setTimeout(() => {console.log(e.target.scrolltop) // Use anti-shake // save the current drop-down position in sessionStorage // sessionStorage.setItem("position", e.target.scrollTop); }, 75); //75ms is best});Copy the code

Effect demo (save current location at intervals) :

Add —-> to do not use anti – shake, did not add the use of anti – shake

Input box search To make a search request at intervals:

<template> <div> <input type="text" @keyup="debounce" /> </div> </template> <script> export default { methods: { debounce: function() { if (timer) { clearTimeout(timer); } timer = setTimeout(() => {console.log("... ); timer = undefined; }, 2000); }}}; </script>Copy the code

The throttle (throttle)

Click multiple times within n seconds. Only one click takes effect

<template> <div> < button@click ="throttle"> </button> </div> </template> <script> let now = +new Date(); export default { methods: { throttle: () => { if (lastTime && now - lastTime < 200) { clearTimeout(timer); console.log("...." ); Timer = setTimeout(() => {console.log(" Click...") ); lastTime = +new Date(); }, 2000); } else { lastTime = now; Timer = setTimeout(() => {console.log(" Click...") ); lastTime = +new Date(); }, 200); }}}}; </script>Copy the code

Effect demonstration:

supplement

Of course, you can also wrap these two methods so that they can be used in multiple places.

/ * * * function image stabilization (only performed last click) * / export const Debounce = (fn, t) = > {let delay = t | | 500; let timer; return function () { let args = arguments; if(timer){ clearTimeout(timer); } timer = setTimeout(() => { timer = null; fn.apply(this, args); }, delay); }}; /* * function Throttle */ export const Throttle = (fn, t) => {let last; let timer; let interval = t || 500; return function () { let args = arguments; let now = +new Date(); if (last && now - last < interval) { clearTimeout(timer); timer = setTimeout(() => { last = now; fn.apply(this, args); }, interval); } else { last = now; fn.apply(this, args); }}};Copy the code