Anti shake
In order to avoid some monitoring events in their own anticipation of the situation, frequent triggering. or triggers events frequently on certain listening commands, such as resize, mousemove, etc.
Unshaken examples
var count = 0, Elem = doc.getElementById('con') function appendCount(e) { console.log(e); Elem.innerHTML = count++ } // Direct monitoring of execution without shaking Elem.addEventListener('mousemove', function() { appendCount() })
This leads to changes in Eelm.innerHTML as long as the mouse moves. Now it looks like it's okay. What if it's a lot of data rendering or requesting thousands of list data?
This will cause the browser to continue to reflow and redraw.
How to prevent tremor?
AppndCount () can only be executed within 1 s of the triggering time of mousemove unless the mousemove method is triggered.
var count = 0, Elem = doc.getElementById('con'); function debounce(fn, waitTime){ // Define timer var timeoutFn = null; return function (){ // Cleaning timer clearTimeout(timeoutFn); // Reset Timer timeoutFn = (() => { fn.apply(this, arguments) },waitTime) } } function appendCount(){ ELem.innerHTML=count++; } Elem.addEventListener('mousemove', debounce(appendCount, 500))
Anti-shaking process
- mousemove triggers debounce()`
-
Define a timer timeout Fn, return the execution content: clear the current timeout Fn timer (timeout Fn = null;), define the execution content.
// debounce() returns content function (){ // Cleaning timer clearTimeout(timeoutFn); // Reset Timer timeoutFn = (() => { fn.apply(this, arguments) },waitTime) }
- When mousemove triggers again, the timeout Fn timer clears again, redefining the execution content
- Only when the last mousemove, the timer is not cleared by debounce(), and the timeout Fn timer is finally executed by fn.apply(this, agruments);
throttle
This is how I understand throttling as opposed to shake-proof: when we want to trigger events that occur only once over a period of time, we can save more resources and network requests.
As an example of AppendCount() above, I just want to trigger an event AppendCount() within 3 seconds.
So what should we do?
var count = 0, Elem = doc.getElementById('con'); function throttle(fn,waitTime){ var timeoutFn = null; return function () { // If a timeout Fn timer exists, wait for timeout Fn to complete if(!timeoutFn){ timeoutFn = (() => { // Vacuum timer clearTimeout(timeoutFn) fn.apply(this, arguments) },waitTime) } } } function appendCount(){ ELem.innerHTML=count++; } Elem.addEventListener('mousemove', throttle(appendCount, 3000))
This is different from shake-proof. After waiting for timeout Fn to be executed, it is emptied by clearTimeout (timeout Fn), so that timeout Fn can be executed again after 3 seconds.
There's another way to write it, which is a little different from the above one. The above one is when throttle is triggered in 1s, but appendCount can only be executed in 4s. But here's the immediate execution. When the first s triggers throttle, appendCount is executed, and then throttle can be repeated after the fourth s.
var count = 0, Elem = doc.getElementById('con'); function throttle(fn, waitTime){ // Define timer, execution state var timeoutFn = null, isRuning = false; return function () { // If not in execution state if(!isRuning){ // Open Execution Status isRuning = true; // Define timer timeoutFn =(() => { fn.apply(this, arguments); // Execution completed, execution status closed isRuning = false; },waitTime) } } } function appendCount(){ ELem.innerHTML=count++; } Elem.addEventListener('mousemove', throttle(appendCount, 3000))