2013-11-24 2 views
1

Итак, у меня есть событие прокрутки. Он загружает вещи, чтобы решить, нужно ли что-то перемещать на странице. Когда вы прокручиваете вниз, он срабатывает. Если вы колесо вниз, перетащите, он стреляет из bazillions и bazillions раз. Как и следовало ожидать, возможно. Вот несколько простых фиктивных кодов для представления последовательности событий.Как прервать предыдущие триггеры событий в jQuery

function scroller() { 
    // 1. A really expensive calculation that depends on the scroll position 
    // 2. Another expensive calculation to work out where should be now 
    // 3. Stop current animations 
    // 4. Animate an object to new position based on 1 and 2 
} 
$(window).on('resize' scroller); 

Не поймите меня неправильно, это обычно точный так что не столько вопрос параллелизмом. Моя анимация внутри вызов события .stop() (как часть №3), поэтому последняя версия всегда * правильная, но она питается большим количеством процессора. Я хотел бы быть ответственным разработчиком здесь, не ожидая, что каждый пользователь получит четырехъядерный ядро ​​i7.

Так к моему вопросу ... Могу ли я убить предыдущие вызовы моему методу от конкретного обработчика событий? Можно ли каким-либо образом вмешиваться в этот пакет «процессов» с очередью/параллельным запуском, чтобы при добавлении нового в стек старые были немедленно завершены? Я уверен, что есть такой подход, который был бы настроен на параллельность, но я не могу думать об этом.

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

+1

Одно из возможных решений является использование своего рода [дребезга] (http://underscorejs.org/#debounce) как ждать какое-то время, как 200мс к посмотреть, будет ли запущено другое событие –

ответ

2

Вы можете гарантировать, что событие будет выпущено максимум один раз за х миллисекунд. Например:

(function ($) { 
    $.fn.delayEvent = function (event, callback, ms) { 
     var whichjQuery = parseFloat($().jquery, 10) 
      , bindMethod = whichjQuery > 1.7 ? "on" : "bind" 
      , timer = 0; 
     $(this)[bindMethod](event, function (event) {     
      clearTimeout (timer); 
      timer = setTimeout($.proxy(callback, this, event), ms); 
     }); 
     return $(this); 
    }; 
})(jQuery); 

$(window).delayEvent("resize", scroller, 1000); 

Минималистичный демо: http://jsfiddle.net/karim79/z2Qhz/6/

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