Могу ли я задержать событие keyup для jquery?

Я использую API-интерфейс rottentomatoes в сочетании с плагином twart typeahead с использованием bootstrap 2.0. Я смог интегрировать API, но проблема, с которой я сталкиваюсь, заключается в том, что после каждого события keyup API вызывается. Это все нормально и денди, но я бы скорее сделал вызов после небольшой паузы, позволяющей пользователю сначала ввести несколько символов.

Вот мой текущий код, который вызывает API после события keyup:

    var autocomplete = $('#searchinput').typeahead()
    .on('keyup', function(ev){

        ev.stopPropagation();
        ev.preventDefault();

        //filter out up/down, tab, enter, and escape keys
        if( $.inArray(ev.keyCode,[40,38,9,13,27]) === -1 ){

            var self = $(this);

            //set typeahead source to empty
            self.data('typeahead').source = [];

            //active used so we aren't triggering duplicate keyup events
            if( !self.data('active') && self.val().length > 0){

                self.data('active', true);

                //Do data request. Insert your own API logic here.
                $.getJSON("http://api.rottentomatoes.com/api/public/v1.0/movies.json?callback=?&apikey=MY_API_KEY&page_limit=5",{
                    q: encodeURI($(this).val())
                }, function(data) {

                    //set this to true when your callback executes
                    self.data('active',true);

                    //Filter out your own parameters. Populate them into an array, since this is what typeahead source requires
                    var arr = [],
                        i=0;

                    var movies = data.movies;

                     $.each(movies, function(index, movie) {
                        arr[i] = movie.title
                        i++;
                     });

                    //set your results into the typehead source 
                    self.data('typeahead').source = arr;

                    //trigger keyup on the typeahead to make it search
                    self.trigger('keyup');

                    //All done, set to false to prepare for the next remote query.
                    self.data('active', false);

                });

            }
        }
    });

Можно ли установить небольшую задержку и избежать вызова API после каждого нажатия клавиши?

Ответ 1

это можно сделать следующим образом:

var autocomplete = $('#searchinput').typeahead().on('keyup', delayRequest);

function dataRequest() {
    // api request here
}

function delayRequest(ev) {
    if(delayRequest.timeout) {
        clearTimeout(delayRequest.timeout);
    }

    var target = this;

    delayRequest.timeout = setTimeout(function() {
        dataRequest.call(target, ev);
    }, 200); // 200ms delay
}

Ответ 2

В общем, это может быть достигнуто с помощью методов setTimeout и clearTimeout:

var timer;

$('#textbox').keyup(function() {
    if (timer) {
        clearTimeout(timer);
    }
    timer = setTimeout('alert("Something cool happens here....");', 500);
});

setTimeout выполнит предоставленный javascript после указанного интервала в миллисекундах. clearTimeout отменяет это выполнение.

Я также подготовил jsFiddle demo, в котором показан фрагмент кода в действии.

Литература:

Ответ 3

Для людей, работающих с v0.11 typeahead.js и используя Bloodhound для получения удаленных предложений, вы можете использовать параметр rateLimitWait для запросов на передачу:

var search = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: {
    url: '/search?q=%QUERY',
    rateLimitWait: 500
  }
});

Ответ 4

Не уверен, какая версия Bootstrap 2.0 используется для typeahead, но v0.9.3 имеет параметр minLength, который скрыт под капотом, но не документирован.

$('#people').typeahead({
  name: 'people',
  prefetch: './names.json',
  minLength: 3
});

Как видно из этого сообщения в блоге: http://tosbourn.com/2013/08/javascript/setting-a-minimum-length-for-your-search-in-typeahead-js/

Ответ 5

Вместо задержки, если вы просто хотите разрешить пользователю вводить несколько символов перед запросом ajax $.getJSON, вы можете изменить инструкцию if, чтобы пользователь вводил минимальное количество символов, например 3, прежде чем запрашивать данные:

if( !self.data('active') && self.val().length >=3){