Могу ли я задержать событие 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){