Подтвердить что ты не робот

Вызов события Throttle в jQuery

У меня есть событие keyup, связанное с функцией, для завершения которой требуется около четверти секунды.

$("#search").keyup(function() {
  //code that takes a little bit to complete
});

Когда пользователь вводит целое слово или, наоборот, быстро нажимает клавиши, функция будет вызываться несколько раз подряд, и для их завершения потребуется некоторое время.

Есть ли способ заблокировать вызовы событий, чтобы, если их несколько подряд, они запускают только тот, который был недавно вызван?

4b9b3361

Ответ 1

Взгляните на jQuery Debounce.

$('#search').keyup($.debounce(function() {
    // Will only execute 300ms after the last keypress.
}, 300));

Ответ 2

Вот потенциальное решение, которое не нуждается в плагине. Используйте логическое значение, чтобы решить, нужно ли делать обратный вызов с клавиатуры или пропустить его.

var doingKeyup = false;

$('input').keyup(function(){
    if(!doingKeyup){
        doingKeyup=true;
        // slow process happens here
        doingKeyup=false;
    }
});

Ответ 3

Вы также можете использовать отличную библиотеку Underscore/_.

Комментарии в Josh answer, в настоящее время наиболее популярные, дебаты о том, действительно ли вы должны дросселировать вызовы или если дебютант - это то, что вы хотите. Разница немного тонкая, но в Underscore есть оба: _.debounce(function, wait, [immediate]) и _.throttle(function, wait, [options]).

Если вы еще не используете Underscore, проверьте его. Это может сделать ваш JavaScript более чистым, и он достаточно лёгкий, чтобы заставить большинство поклонников библиотеки останавливаться.

Ответ 4

Вот простой способ сделать это с помощью 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);

Ответ 5

Я столкнулся с этим вопросом, пересмотрев изменения на . Они добавили свой собственный метод для отладки и дросселирования. Похоже, он может быть таким же, как в 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));

Ответ 6

Что-то вроде этого кажется простым (без внешних библиотек) для быстрого решения (обратите внимание на 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