Как ограничить обработку события один раз в X секунд с помощью jQuery / javascript?
для быстрой стрельбы keypress
событие, я хочу ограничить обработку события максимум один раз за X секунд.
Я уже использую jQuery для обработки событий, поэтому предпочтительным было бы решение на основе jQuery, хотя vanilla javascript тоже хорош.
этот jsfiddle показывает нажатие клавиши стрельбы быстро без каких-либо ограничений на обработку
этот jsfiddle реализует ограничение обработки один раз в 0,5 секунды в vanilla JS с помощью
setTimeout()
у меня вопрос
есть ли у jQuery встроенный способ сделать это? Я ничего не вижу в
.on()
docsЕсли нет, есть ли лучший шаблон для этого в vanilla JS, чем я использовал в своем второй пример jsfiddle?
3 ответов
есть ли у jQuery встроенный способ сделать это?
нет.
если нет, есть ли лучший шаблон для этого в vanilla JS, чем я использовал во втором примере jsfiddle?
вместо setTimeout
и флаги, вы можете отслеживать, когда обработчик был вызван в последний раз, и вызывать его только после определенного интервала. Это называется регулирование и есть различные способы осуществить это.
в своей простейшей форме вы просто должны игнорировать каждый вызов, который сделан в течение времени lastCall + interval
, так что происходит только один вызов в каждом интервале.
Е. Г. здесь-это функция, которая возвращает новую функцию, которая может быть вызван только один раз каждые X миллисекунд:
function throttle(func, interval) {
var lastCall = 0;
return function() {
var now = Date.now();
if (lastCall + interval < now) {
lastCall = now;
return func.apply(this, arguments);
}
};
}
который вы можете использовать как
$("#inputField").on("keypress", throttle(function(event) {
$("div#output").append("key pressed <br/>");
}, 500));
As Esailija упоминает в комментарии, может быть, это не дросселирование, что вам нужно, но debouncing. Это аналогичная, но несколько иная концепция. В то время как регулирование означает, что что-то должно происходить только раз в x миллисекунд, debouncing означает, что что-то должно произойти, только если это не произошло за последние X миллисекунд.
типичный пример:scroll
событие. Обработчик событий прокрутки будет вызываться очень часто, потому что событие в основном запускается непрерывно. Но, возможно, вы хотите выполнить обработчик только тогда, когда пользователь прекратил прокрутку, а не пока он будет прокручиваться.
простой способ достичь этого-использовать тайм-аут и отменить его, если функция вызывается снова (и тайм-аут еще не работать):
function debounce(func, interval) {
var lastCall = -1;
return function() {
clearTimeout(lastCall);
var args = arguments;
var self = this;
lastCall = setTimeout(function() {
func.apply(self, args);
}, interval);
};
}
недостатком этой реализации является то, что вы не можете вернуть значение из обработчика события (например,return false;
). Возможно, есть реализации, которые могут сохраните эту функцию (при необходимости).
Я бы сделал это дросселирование событий так просто:
$("#inputField").on("keypress", function(event) {
var now = Date.now();
var nt = $(this).data("lastime") || now;
if( nt > now ) return;
$(this).data("lastime", now + 500);
$("div#output").append("key pressed <br/>");
});
запись когда в последний раз вы обработали событие было, и каждый раз, когда вы получаете событие, сделать проверку, чтобы увидеть, если интервал истек.