2013-03-17 2 views
2

Один из моих сценариев вызывает функцию в какой-то момент из-за события changeCursor (я использую редактор ACE). Это замедляет движение курсора, когда я нажимаю его много раз.Как игнорировать все, кроме последней из серии быстрых событий Javascript?

Я действительно хочу, чтобы эта функция вызывалась, но это нормально, если она вызывается только после того, как мой курсор остановился (т. Е. Мне не нужно видеть промежуточные состояния).

Есть ли стандартный способ игнорировать все, кроме последнего события?

ответ

4

Классический способ использовать короткий тайм-аут:

var cursorTimer; 
function changeCursor() { 
    clearTimeout(cursorTimer); 
    cursorTimer = setTimeout(function() { 
     // process the actual cursor change here 
    }, 500); 

} 

Ваш обычный код может продолжать вызов changeCursor() каждый раз, когда она меняется (так же, как это происходит сейчас), но фактический код внутри setTimeout() будет выполнять только когда в последние 500 мс не произошло событий смены курсора. Вы можете отрегулировать это значение времени по желанию.

Единственный способ узнать, что события остановились, - это подождать некоторое короткое время и не обнаружить дальнейшего движения (что и как это делается). Обычно аналогичная логика используется для событий прокрутки.

+0

Is clearTimeout необходимо? Не будет ли курсорTimer = setTimeout автоматически уничтожить предыдущий setTimeout? – Christophe

+0

@Christophe - требуется 'clearTimeout()'. Установка 'cursorTimer' в новое значение НЕ останавливает предыдущий таймер, поэтому, если вы не очистите предыдущий, он все равно будет гореть, что НЕ является тем, что вы хотите, поскольку вы не получите эффект, который вы ищете (вы будете получить один таймер для каждого события, а не только один, когда пользователь делает паузу). – jfriend00

+0

получил, спасибо. +1, я не знал об этом классическом шаблоне. – Christophe

1

Это может быть избыток для этой одной проблемы, но проверьте RxJS: http://reactive-extensions.github.com/RxJS/#What RxJS?

Он добавляет некоторые довольно мощные методы для «запросов/манипулирования» потоками событий в JavaScript. https://github.com/Reactive-Extensions/RxJS/wiki/Observable

В этом случае метод «дроссельной заслонки» - это то, что ваш после. Вот пример, который использует Throttle с событием keyup для создания автозаполнения совпадений в википедии. https://github.com/Reactive-Extensions/RxJS-Examples/blob/master/autocomplete/autocomplete.js

// Get all distinct key up events from the input and only fire if long enough and distinct 
var keyup = Rx.Observable.fromEvent(input, 'keyup').select(function (e) { 
    return e.target.value; // Project the text from the input 
}) 
.where(function (text) { 
    return text.length > 2; // Only if the text is longer than 2 characters 
}) 
.throttle(
    750 // Pause for 750ms 
) 
.distinctUntilChanged(); // Only if the value has changed 
Смежные вопросы