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)
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