First in my personal website, the article link function of anti – shake and throttling is what??
I was once asked this question in an interview, and I was young and ignorant…
Later, I encountered a scene in my work: when I entered the name, I went to the server to check whether the name was repeated, but I found that the previous code did not limit the input and sent a request once. I couldn’t stand it anymore, so I added the anti-shake function to the utils of the project. Just to make a summary, deepen the impression.
Functions such as buffeting and throttling are used to control the frequency of events. There are many application scenarios, such as continuous input in the input box, remote verification of input content, multiple click events, onScroll and so on. To illustrate, consider a scenario where the mouse slides over a div, triggering the onMousemove event, and the text inside it shows the coordinates of the current mouse.
<style>
#box {
width: 1000px;
height: 500px;
background: #ccc;
font-size: 40px;
text-align: center;
line-height: 500px;
}
</style>
<div id="box"></div>
<script>
const box = document.getElementById('box')
box.onmousemove = function (e) {
box.innerHTML = `${e.clientX}.${e.clientY}`
}
</script>
Copy the code
It works like this:
In the above scenario, we do not want to execute once triggered, which requires anti-shake or throttling. Let’s see what they can do for us.
Image stabilization
Function tremble, here jitter is the execution of the meaning, and the general jitter is continuous, many times. Let’s say the function is executed multiple times, and we want it to cool off before we execute it. That is, the function does not execute at all while the event is being fired, waiting for some time after the last event has been fired. Take a look at the results:
Break down the requirements:
- Continuous trigger non-execution
- Does not trigger for a period of time before executing
So how to achieve these goals? The timer calls the function that you want to execute, passing arguments in.
Encapsulating a function so that the event listener that keeps firing is the function that we encapsulate, passing in the target function as a callback (func), and waiting a while to execute the target function
function debounce(func, delay) {
return function() {
setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
Copy the code
The second point is realized, and the first point is: continuous triggering does not execute. So let’s think about, what makes our function execute? It’s setTimeout up there. OK, so now the problem is to keep firing, no setTimeout. This allows the timer to be cleared directly while the event continues to fire.
function debounce(func, delay) {
let timeout
return function() {clearTimeout(timeout) // If this continues, the timer is cleared and the timer callback is not executed. timeout =setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
Copy the code
Usage:
box.onmousemove = debounce(function (e) {
box.innerHTML = `${e.clientX}.${e.clientY}`}, 1000).Copy the code
The throttle
The idea of throttling is to allow a function to execute sparingly, rather than arbitrarily once triggered. What does abstinence mean? Just do it once in a period of time. Again, let’s break it down:
- Continuous triggering does not occur more than once
- Do it at a certain time
It works like this:
Think about it, it keeps firing, it doesn’t execute, but it does when the time is up. Capture one key point: timing of execution. To control the timing of execution, we can use a switch combined with timer setTimeout.
The precondition for the function execution is that the switch is on, and when it is triggered continuously, the switch is kept off. When setTimeout reaches the time, the switch is turned on again, and the function will be executed. Let’s see how the code works:
function throttle(func, deley) {
let run = true
return function () {
if(! run) {return// If the switch is off, do not execute the following code} run =false// Run will always befalse, will stop at the top of the judgmentsetTimeout(() => {
func.apply(this, arguments)
run = true// When the timer is up, the switch will be turned on and our function will be executed}, deley)}}Copy the code
When called:
box.onmousemove = throttle(function (e) {
box.innerHTML = `${e.clientX}.${e.clientY}`}, 1000).Copy the code
In this way, throttling is realized. Throttling can also be controlled by time interval, which is to record the execution time of the last function and compare it with the current time. If the time difference between the current time and the last execution time is greater than one value, the execution is performed.
Let run= true override false when throttling
You can look inside throttle and when you call it. First look inside the function and break down the structure:
function throttle(func, deley) {
return function() {// execute func}}Copy the code
What about when you call it? Break it down too:
throttle(function() {// target function content}, 1000)Copy the code
The result of throttle is a function call within its return. That is to say, the mouse-over listener is actually the function that is being returned, which is constantly being fired, and throttle just provides a scope to declare a run switch variable with a closure. Because of the closure, the run variable will remain undestroyed. Let run = true is declared only once in this closure, but it is not continuously executed, so the judgment inside the return function is not overwritten by it. According to the printout, this is indeed the case:
conclusion
The setTimeout is cleverly used to control the timing of function execution. The advantage is obvious, which can save performance and avoid multiple triggering of complex business logic resulting in page lag.
Welcome to pay attention to my public number: a front-end, share my understanding of the front-end knowledge from time to time