2015-03-31 3 views
7

Это чек на мое понимание requestAnimationFrame. Мне нужна функция debounce, так как я выполняю какое-то взаимодействие с DOM каждый раз при изменении размера окна, и я не хочу перегружать браузер. Типичная функция debounce будет вызывать только переданную функцию один раз за интервал; интервал обычно является вторым аргументом. Я предполагаю, что для большого количества пользовательского интерфейса оптимальный интервал - это самый короткий промежуток времени, который не перегружает браузер. Мне кажется, что это именно то, что requestAnimationFrame бы сделать:Это хорошая идея использовать requestAnimationFrame в функции debounce?

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. По моему мнению, это будет как можно скорее приостановить работу с передачей, но любые вызовы, поступающие быстрее, чем браузер может обрабатывать, будут сброшены. Это должно обеспечить максимально возможное взаимодействие. Я на правильном пути? Или я недопонимаю requestAnimationFrame?

(Конечно, это работает только на современных браузерах, но есть легкая polyfills для requestAnimationFrame, которые просто падают обратно SetTimeout.)

+1

Если речь идет о перерисовке, и вам нужна плавная анимация, вы хотите * дросселировать * не * debouncing *. Пожалуйста, перечитайте сообщение в блоге, которое вы связали, чтобы узнать, в чем разница: debounce не «вызывает переданную функцию один раз за интервал» – Bergi

+1

@Bergi благодарит за это. Я думал об этом в первый раз, но я снова его просмотрел и прочитал заметки Бен Альмана о различиях http://benalman.com/projects/jquery-throttle-debounce-plugin/, и я думаю, что вы можете быть правы - хотя, я думаю, с быстрым браузером, который может быстро реагировать, он сводит к минимуму разницу между ними. – carpeliam

+0

Думал то же самое. Так рад, что нашел этот пост. Было бы неплохо добавить параметр контекста, который будет использоваться вместо 'var obj = this'. Таким образом, людям не придется использовать 'bind' перед вызовом и сохраняет создание еще одной области возможностей – Dogoku

ответ

1

Это будет работать.

Он имеет один нюанс, который может или не может быть важен для вас:

Если страница в настоящее время не видна, анимация на этой странице, может быть задушила сильно, так что они часто не обновляются и таким образом потребляют маленький CPU энергия.

Так что, если вы по какой-то причине заботы об этом для функции вы дребезг, вы лучше использовать setTimeout(fn, 0)

В противном случае, если вы используете это для анимации, это предполагаемое использование requestAnimationFrame

+0

, что имеет большой смысл для моего конкретного случая - я выполняю некоторое взаимодействие с DOM на мероприятии« resize », и если моя вкладка не активен, я в порядке с тем, что взаимодействие не происходит, пока пользователь не переключится на мою вкладку. – carpeliam

Смежные вопросы