“This is the first day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021”
Simulation scenario
In the daily development process, we often encounter frequently triggered operations, such as scroll of the page, mousemove of the mouse, keydown of the keyboard and so on. For example, when entering keywords in the Baidu search box, relevant associative words will appear below to predict the content that users want to search. Every time we type in the text, it will be triggered frequently.
To visualize frequent triggering, I’ve written a simple piece of code.
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Image stabilization</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 300px;
height: 300px;
text-align: center;
line-height: 300px;
background-color: gray;
color: #fff;
font-size: 30px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
let box = document.querySelector('.box')
let num = 0
function addNum(){
box.innerHTML = num++
}
box.addEventListener('mousemove',addNum)
</script>
</body>
</html>
Copy the code
In the driven graph, we can see that the number increases frequently as the mouse moves. Of course, this is exactly what we want in this program. It may not cost much performance for changes in numbers, but it will lag if network requests are frequent.
To solve this problem, we can use anti-shake and throttling.
Today we will introduce anti-shake first.
What is anti-shake
The so-called shaking prevention means that the function is executed after the event is triggered for n seconds. If the event is triggered again within n seconds, the function execution time will be recalculated.Copy the code
Again, using the mouse movement example, suppose we set the time to 1s, if we trigger the mouse movement event and continue to move the mouse for 1s, then the function will not execute and the number will not continue to increase; If we stop firing the event, then after 1s, the function will execute and the number will increase.
Now let’s do anti-shake.
The realization of anti – shake
Not an immediate version
function debounce(func,time){
let timer
return function(){
if(timer)
clearTimeout(timer)
timer = setTimeout(func,time)
}
}
Copy the code
The usage method is as follows:
box.addEventListener('mousemove',debounce(addNum,1000))
Copy the code
We find that we have achieved the desired effect. If we continue firing for 1s, the function will not be executed. Instead, we will restart the timer and execute the function 1 second after we stop firing the event. The problem with this is that the function is not executed the first time the event is raised.
We need to make some simple changes.
Immediate release
function debounceImmediate(func,time){
let timer
return function(){
if(timer)
clearTimeout(timer)
constcallNow = ! timer timer =setTimeout(() = >{
timer = null
},time)
// The first time the event is triggered, there is no timer, so the function is executed once
if(callNow)
func()
}
}
Copy the code
We can add an immediate parameter to the anti-shake function, which is true to execute the version immediately.
The final version
Although we have achieved the anti-shock effect, calling debounce directly causes this in addNum to point to the window without the original arguments.
So here is the final version of the stabilization function (immediate parameter, change this, with arguments).
function debounceFinal(func,delay,immediate) {
let timer;
return function(){
let context = this
let args = arguments
if(timer) clearTimeout(timer)
if(immediate){
constcallNow = ! timer timer =setTimeout(() = > {
timer = null
}, delay);
if(callNow) func.apply(context,args)
}else{
timer = setTimeout(() = >{ func.apply(context,args) }, delay); }}}Copy the code
Call the addNum function
function addNum(e){
// Add this and e as tests
console.log(this)
console.log(e)
box.innerHTML = num++
}
box.onmousemove = debounceFinal(addNum,1000.true)
Copy the code
The console output is shown below.
conclusion
The above is the introduction of the anti – shake function and the implementation of the code, the next period we will introduce another scheme – throttling.
If there is a mistake, welcome to point out!