Как сделать мой live jQuery-поиск ждать секунды, прежде чем выполнять поиск?
У меня есть вход для поиска, который отправляет данные из ввода в php файл по мере ввода. Файл php выполняет поиск в моей базе данных и отображает список параметров поиска. Вы знаете, живой стиль в стиле ajax.
Моя проблема в том, что если вы наберете что-то действительно быстрое, оно может просто провести поиск с первых 1 или 2 букв, даже если набрано еще 10. Это вызывает несколько проблем.
Мой jQuery выглядит примерно так:
$(document).ready(function(){
$('#searchMe').keyup(function(){
lookup(this.value);
});
});
и
function lookup(searchinput) {
if(searchinput.length == 0) {
// Hide the suggestion box.
$("#suggestions").hide();
} else {
$('#loading').fadeIn();
$.post("/RPCsearch.php", {queryString: ""+searchinput+""}, function(data){
if(data.length > 0) {
$("#suggestions").html(data).show();
$('#loading').fadeOut();
}
});
}
} // lookup
Итак, мне просто интересно, как я могу сделать это так, чтобы мой script ждал, пока я не закончил печатать до запуска функции? В моей логике говорится, что, если ключ не был нажат на 200 микросекунд, запустите функцию, иначе немного задержитесь.
Как это делается?
Ответы
Ответ 1
Просто, используя setTimeout
. Конечно, вы хотите, чтобы сразу один таймер заходил, поэтому важно использовать clearTimeout
в начале функции...
$(function() {
var timer;
$("#searchMe").keyup(function() {
clearTimeout(timer);
var ms = 200; // milliseconds
var val = this.value;
timer = setTimeout(function() {
lookup(val);
}, ms);
});
});
Ответ 2
Вам может быть интересен мой bindDelayed
мини-плагин jQuery. Это:
- Позволяет указать задержку перед началом запроса
- Автоматически отменяет любые предыдущие запросы, которые должны были быть отправлены
- Автоматически отменяет любые входящие в эфир запросы XHR, которые выполнялись, когда вы делаете свой запрос
- Только вызов вашего обратного вызова для последнего запроса
- Если пользователь набирает "s", ждет достаточно долго, чтобы запрос вышел, а затем набирает "a", а ответ "s" возвращается до ответа "sa", вам не придется справиться с этим.
Ответ на исходный вопрос с помощью bindDelayed
будет выглядеть так:
// Wait 200ms before sending a request,
// avoiding, cancelling, or ignoring previous requests
$('#searchMe').bindDelayed('keyup',200,'/RPCsearch.php',function(){
// Construct the data to send with the search each time
return {queryString:this.value};
},function(html){
// Use the response, secure in the knowledge that this is the right response
$("#suggestions").html(html).show();
},'html','post');
В случае, если мой сайт не работает, здесь приведен код плагина для потомков:
(function($){
// Instructions: http://phrogz.net/jquery-bind-delayed-get
// Copyright: Gavin Kistner, [email protected]
// License: http://phrogz.net/js/_ReuseLicense.txt
$.fn.bindDelayed = function(event,delay,url,dataCallback,callback,dataType,action){
var xhr, timer, ct=0;
return this.on(event,function(){
clearTimeout(timer);
if (xhr) xhr.abort();
timer = setTimeout(function(){
var id = ++ct;
xhr = $.ajax({
type:action||'get',
url:url,
data:dataCallback && dataCallback(),
dataType:dataType||'json',
success:function(data){
xhr = null;
if (id==ct) callback.call(this,data);
}
});
},delay);
});
};
})(jQuery);
Ответ 3
Вам действительно стоит взглянуть на использование плагина jQuery autocomplete. Я считаю, что этот плагин очень полезен, и он уже делает то, что вам нужно. Посмотрите, в частности, на задержку option, которую вы можете настроить, чтобы изменить время ожидания плагина после нажатия клавиши.
Ответ 4
1 решение в psuedocode:
OnKeyPress()
txt = getTxt
sleep(200)
newTxt = getTxt
if (txt == newTxt) // nothing has been typed so do something
run my thing
Ответ 5
этот счастлив
$(document).ready(function(){
$("#searchMe").keyup(function () {
try{window.clearTimeout(timeoutID);}catch(e){}
timeoutID = window.setTimeout(run, 2000); //delay
function run()
{ //dowhatev
var text = $("#searchMe").val();
//$("#showit").html(text);
}
});
});
Ответ 6
Я нашел лучший успех при подключении события к нажатиям клавиш, вводам клавиш и вводам ключей. Safari/FireFox/IE, похоже, обрабатывают специальные нажатия клавиш (delete, backspace и т.д.) Немного по-другому, но использование всех событий вместе, похоже, покрывает его. Единственный способ, с помощью которого выполняются все события, - это использовать setTimeout, чтобы при каждом запуске он просто сбрасывал таймер, и в конечном итоге обратный вызов запускается только один раз.
var delay = 200;
var search_timer = null;
$("#searchMe").keydown(function(e) {
if(search_timer) {
clearTimeout(search_timer);
}
search_timer = setTimeout(lookup, delay);
});
$("#searchMe").keypress(function(e) {
if(search_timer) {
clearTimeout(search_timer);
}
search_timer = setTimeout(lookup, delay);
});
$("#searchMe").keyup(function(e) {
if(search_timer) {
clearTimeout(search_timer);
}
search_timer = setTimeout(lookup, delay);
});