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.
For the usage of timers, please go to: the usage of timers in JS
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.
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.
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 demonstration (save the current position for a period of time) : add —-> to 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.
// The event is triggered n seconds before the callback is executed, if it is triggered within n seconds, Function debounce(fn, delay) { let t = delay || 500 let timer return function() { clearTimeout(timer) timer = setTimeout(() => { // Apply (this, arguments)}, t)}} // throttling (specify that only one function can be fired in a unit of time. If multiple functions are fired in a unit of time, Take effect only once) function throttle (fn, delay) {let t = delay | | 500 let the timer return function () {if (! Timer) {timer = setTimeout(() => {// For the convenience of the next timer timer = null fn. Apply (this, arguments)}, t)}}}Copy the code