2015-03-31 12 views
7

Questo è un controllo sulla mia comprensione di requestAnimationFrame. Ho bisogno di una funzione debounce, poiché sto facendo qualche interazione DOM ogni volta che la finestra viene ridimensionata e non voglio sovraccaricare il browser. Una funzione di debounce tipica chiamerà la funzione passata solo una volta per intervallo; l'intervallo è solitamente il secondo argomento. Presumo che per un sacco di lavoro dell'interfaccia utente, l'intervallo ottimale è il più breve tempo che non sovraccarichi il browser. Mi sembra che questo è esattamente ciò requestAnimationFrame farebbe:È una buona idea usare requestAnimationFrame con una funzione di rimbalzo?

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); 
    }; 
} 

Il codice di cui sopra è un rip-off diretto the above debounce link, ma con requestAnimationFrame usato al posto di setTimeout. A mio avviso, questo accoderà la funzione passata il prima possibile, ma tutte le chiamate che arrivano più velocemente di quanto il browser possa gestire verranno eliminate. Questo dovrebbe produrre l'interazione più liscia possibile. Sono sulla buona strada? O sto fraintendendo lo requestAnimationFrame?

(Naturalmente questo funziona solo su browser moderni, ma ci sono semplici polyfills per requestAnimationFrame che appena cadono di nuovo a setTimeout.)

+1

Se si tratta di ridisegnare e si desidera un'animazione fluida, si desidera * limitazione * non * debouncing *. Per favore rileggi il post sul blog che hai collegato per vedere qual è la differenza - il rimbalzo non è "chiama la funzione passata una volta per intervallo" – Bergi

+1

@Bergi ringrazia per quello. Ci ho pensato la prima volta, ma l'ho rivisitato e ho letto gli appunti di Ben Alman sulle differenze http://benalman.com/projects/jquery-throttle-debounce-plugin/, e penso che potresti avere ragione - Tuttavia, penso che con un browser veloce in grado di rispondere rapidamente, riduce al minimo la differenza tra i due. – carpeliam

+0

Stavo pensando la stessa cosa. Sono contento di aver trovato questo post. Sarebbe una buona idea aggiungere un parametro di contesto da usare al posto di 'var obj = this'. In questo modo le persone non dovranno usare 'bind' prima di chiamare e salvare la creazione di un altro ambito di funzione – Dogoku

risposta

1

Questo funzionerà.

E 'un avvertimento che può o non può essere importante per voi:

Se la pagina non è attualmente visibile, animazioni su quella pagina possono essere strozzato pesantemente in modo che non si aggiornano spesso e consumano quindi poca potenza della CPU.

Quindi, se per qualche motivo la cura di questo per la funzione che si sta debouncing, si sta meglio utilizzando setTimeout(fn, 0)

caso contrario, se si sta utilizzando questo per le animazioni, questo è l'utilizzo previsto di requestAnimationFrame

+0

che ha molto senso per il mio caso particolare - Sto facendo qualche interazione DOM sull'evento' resize', e se la mia scheda non è attivo, sto bene con quell'interazione che non succede fino a quando l'utente non torna alla mia scheda. – carpeliam