Вызовы событий Throttle в jQuery - PullRequest
41 голосов
/ 10 сентября 2011

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

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

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

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

Ответы [ 7 ]

59 голосов
/ 10 сентября 2011

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

$('#search').keyup($.debounce(function() {
    // Will only execute 300ms after the last keypress.
}, 300));
8 голосов
/ 10 сентября 2011

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

var doingKeyup = false;

$('input').keyup(function(){
    if(!doingKeyup){
        doingKeyup=true;
        // slow process happens here
        doingKeyup=false;
    }
});
3 голосов
/ 26 октября 2016

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

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

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

1 голос
/ 07 августа 2014

Вот простой способ сделать это с 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);
0 голосов
/ 18 февраля 2019

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

  1. Ожидание через некоторое время после последнего вызова

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

function throttle(time, func) {
  if (!time || typeof time !== "number" || time < 0) {
      return func;
  }

  var throttleTimer = 0;

  return function() {
    var args = arguments;
    clearTimeout(throttleTimer);
    throttleTimer = setTimeout(function() {
      func.apply(null, args);
    }, time);
  }
}

Вызывает данную функцию не чаще, чем заданное количество времени

Следующее полезно для очистки журналов

function throttleInterval(time, func) {
  if (!time || typeof time !== "number" || time < 0) {
      return func;
  }

  var throttleTimer = null;
  var lastState = null;
  var eventCounter = 0;
  var args = [];

  return function() {
    args = arguments;
    eventCounter++;
    if (!throttleTimer) {
      throttleTimer = setInterval(function() {
        if (eventCounter == lastState) {
          clearInterval(throttleTimer);
          throttleTimer = null;
          return;
        }

        lastState = eventCounter;
        func.apply(null, args);
      }, time);
    }
  }
}

Использование очень просто:

Следующий код ожидает 2 секунды после последнего нажатия клавиши в inputBox, а затем вызывает функцию, которую нужно регулировать.

$("#inputBox").on("input", throttle(2000, function(evt) {
  myFunctionToThrottle(evt);
}));

Вот пример, где вы можете проверить оба: нажмите (CodePen)

0 голосов
/ 08 февраля 2014

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

Что-то вроде этого кажется самым простым (без внешних библиотек) для быстрого решения (примечание 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...