2015-03-31 106 views
7

這是檢查我對​​的理解。我需要一個debounce函數,因爲每次窗口大小調整時我都會進行一些DOM交互,而且我不想讓瀏覽器過載。典型的去抖動功能只會在每個間隔調用一次傳遞函數;間隔通常是第二個參數。我假設對於大量的UI工作來說,最佳時間間隔是不會使瀏覽器過載的最短時間。這在我看來,這正是​​會做:在debounce函數中使用requestAnimationFrame是個好主意嗎?

var debounce = function (func, execAsap) { 
    var timeout; 

    return function debounced() { 
    var obj = this, args = arguments; 
    function delayed() { 
     if (!execAsap) 
     func.apply(obj, args); 
     timeout = null; 
    }; 

    if (timeout) 
     cancelAnimationFrame(timeout); 
    else if (execAsap) 
     func.apply(obj, args); 

    timeout = requestAnimationFrame(delayed); 
    }; 
} 

上面的代碼是從the above debounce link直接敲竹槓,但使用requestAnimationFrame用來代替的setTimeout。根據我的理解,這將盡快排隊傳入函數,但任何進入速度超過瀏覽器的函數都可能會丟失。這應該會產生最平穩的交互。我在正確的軌道上嗎?還是我誤解了​​?

(當然,這僅適用於現代的瀏覽器,但也有容易polyfills爲requestAnimationFrame,只是回落到setTimeout的。)

+1

如果是關於重畫,並且你想要一個流暢的動畫,你想*節流*不*反彈*。請重新閱讀已鏈接的博客文章,瞭解它們之間的區別 - debounce不是「每個區間調用一次傳遞的函數」 – Bergi 2015-03-31 02:32:43

+1

@Bergi感謝。我第一次考慮這個問題,但我重新考慮了這個問題,並閱讀了Ben Alman關於差異的筆記http://benalman.com/projects/jquery-throttle-debounce-plugin/,我想你可能是對的 - 儘管如此,我認爲使用快速響應的快速瀏覽器可以最大限度地減少兩者之間的差異。 – carpeliam 2015-03-31 16:43:11

+0

想着同樣的事情。很高興我找到了這篇文章。添加一個上下文參數來代替'var obj = this'是個好主意。這樣,人們在調用之前不必使用'bind',並保存創建多個函數作用域 – Dogoku 2015-07-03 00:17:55

回答

1

這將工作。

它有一個警告,可能會或可能不會對你很重要:

如果頁面當前不可見,該網頁上的動畫可以重來節流,使他們不經常更新,因此消耗很小的CPU功率。

因此,如果您由於某種原因在乎這對你是去抖動功能,你使用setTimeout(fn, 0)

否則,如果您使用的是本作的動畫更好,這是​​

使用目的
+0

,這對我的特殊情況有很大的意義 - 我在'resize'事件上做了一些DOM交互,並且如果我的選項卡沒有激活,直到用戶切換回我的選項卡後,我才確定這種交互沒有發生。 – carpeliam 2015-03-31 02:11:11

相關問題