Ответ 1
Взгляните на jQuery Debounce.
$('#search').keyup($.debounce(function() {
// Will only execute 300ms after the last keypress.
}, 300));
У меня есть событие keyup
, связанное с функцией, для завершения которой требуется около четверти секунды.
$("#search").keyup(function() {
//code that takes a little bit to complete
});
Когда пользователь вводит целое слово или, наоборот, быстро нажимает клавиши, функция будет вызываться несколько раз подряд, и для их завершения потребуется некоторое время.
Есть ли способ заблокировать вызовы событий, чтобы, если их несколько подряд, они запускают только тот, который был недавно вызван?
Взгляните на jQuery Debounce.
$('#search').keyup($.debounce(function() {
// Will only execute 300ms after the last keypress.
}, 300));
Вот потенциальное решение, которое не нуждается в плагине. Используйте логическое значение, чтобы решить, нужно ли делать обратный вызов с клавиатуры или пропустить его.
var doingKeyup = false;
$('input').keyup(function(){
if(!doingKeyup){
doingKeyup=true;
// slow process happens here
doingKeyup=false;
}
});
Вы также можете использовать отличную библиотеку Underscore/_.
Комментарии в Josh answer, в настоящее время наиболее популярные, дебаты о том, действительно ли вы должны дросселировать вызовы или если дебютант - это то, что вы хотите. Разница немного тонкая, но в Underscore есть оба: _.debounce(function, wait, [immediate])
и _.throttle(function, wait, [options])
.
Если вы еще не используете Underscore, проверьте его. Это может сделать ваш JavaScript более чистым, и он достаточно лёгкий, чтобы заставить большинство поклонников библиотеки останавливаться.
Вот простой способ сделать это с помощью JQuery.
/* delayed onchange while typing jquery for text boxes widget
usage:
$("#SearchCriteria").delayedChange(function () {
DoMyAjaxSearch();
});
*/
(function ($) {
$.fn.delayedChange = function (options) {
var timer;
var o;
if (jQuery.isFunction(options)) {
o = { onChange: options };
}
else
o = options;
o = $.extend({}, $.fn.delayedChange.defaultOptions, o);
return this.each(function () {
var element = $(this);
element.keyup(function () {
clearTimeout(timer);
timer = setTimeout(function () {
var newVal = element.val();
newVal = $.trim(newVal);
if (element.delayedChange.oldVal != newVal) {
element.delayedChange.oldVal = newVal;
o.onChange.call(this);
}
}, o.delay);
});
});
};
$.fn.delayedChange.defaultOptions = {
delay: 1000,
onChange: function () { }
}
$.fn.delayedChange.oldVal = "";
})(jQuery);
Я столкнулся с этим вопросом, пересмотрев изменения на zurb-foundation. Они добавили свой собственный метод для отладки и дросселирования. Похоже, он может быть таким же, как в jQuery-debounce @josh3736, упомянутом в его ответе.
На своем веб-сайте:
// Debounced button click handler
$('.button').on('click', Foundation.utils.debounce(function(e){
// Handle Click
}, 300, true));
// Throttled resize function
$(document).on('resize', Foundation.utils.throttle(function(e){
// Do responsive stuff
}, 300));
Что-то вроде этого кажется простым (без внешних библиотек) для быстрого решения (обратите внимание на coffeescript):
running = false
$(document).on 'keyup', '.some-class', (e) ->
return if running
running = true
$.ajax
type: 'POST',
url: $(this).data('url'),
data: $(this).parents('form').serialize(),
dataType: 'script',
success: (data) ->
running = false