我对javascript中的“去抖动”功能感兴趣,写在这里:http ://davidwalsh.name/javascript-debounce- function
不幸的是,代码解释得不够清楚,我无法理解。谁能帮我弄清楚它是如何工作的(我在下面留下了我的评论)。简而言之,我真的不明白这是如何工作的
// Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; };
编辑:复制的代码片段以前callNow在错误的位置。
callNow
问题中的代码与链接中的代码略有不同。在链接中,有一个检查(immediate && !timeout)BEFORE 创建一个新的 timout。拥有它之后会导致立即模式永远不会触发。我已经更新了我的答案,以从链接中注释工作版本。
(immediate && !timeout)
function debounce(func, wait, immediate) { // 'private' variable for instance // The returned function will be able to reference this due to closure. // Each call to the returned function will share this common timer. var timeout; // Calling debounce returns a new anonymous function return function() { // reference the context and args for the setTimeout function var context = this, args = arguments; // Should the function be called now? If immediate is true // and not already in a timeout then the answer is: Yes var callNow = immediate && !timeout; // This is the basic debounce behaviour where you can call this // function several times, but it will only execute once // [before or after imposing a delay]. // Each time the returned function is called, the timer starts over. clearTimeout(timeout); // Set the new timeout timeout = setTimeout(function() { // Inside the timeout function, clear the timeout variable // which will let the next execution run when in 'immediate' mode timeout = null; // Check if the function already ran with the immediate flag if (!immediate) { // Call the original function with apply // apply lets you define the 'this' object as well as the arguments // (both captured before setTimeout) func.apply(context, args); } }, wait); // Immediate mode and no wait timer? Execute the function.. if (callNow) func.apply(context, args); } } ///////////////////////////////// // DEMO: function onMouseMove(e){ console.clear(); console.log(e.x, e.y); } // Define the debounced function var debouncedMouseMove = debounce(onMouseMove, 50); // Call the debounced function on every mouse move window.addEventListener('mousemove', debouncedMouseMove);