2009-07-23 9 views
16

Tengo una entrada de búsqueda que envía datos de una entrada a un archivo php mientras escribo. El archivo php hace una búsqueda en mi base de datos y muestra una lista de opciones de búsqueda. Ya sabes, la búsqueda en vivo de estilo ajax.¿Cómo hago que mi búsqueda jQuery en vivo espere un segundo antes de realizar la búsqueda?

Mi problema es que, si escribe algo realmente rápido, podría realizar una búsqueda de las primeras 1 o 2 letras aunque se hayan tipeado otras 10. Esto causa algunos problemas.

Mi jQuery se ve un poco como esto:

$(document).ready(function(){ 
    $('#searchMe').keyup(function(){ 
    lookup(this.value); 
    }); 
}); 

y

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 

Así que tengo curiosidad, ¿cómo puedo hacer para que mi script espera hasta que haya terminado de escribir antes de ejecutar la función? Mi lógica dice algo así como si una tecla no se ha presionado durante 200 micro segundos, ejecuta la función, de lo contrario, espera un poco.

¿Cómo se hace esto?

solución

Respuesta

48

Fácil, usando setTimeout. Por supuesto solo deseas un temporizador funcionando al mismo tiempo, por lo que es importante utilizar clearTimeout al comienzo de la función ...

$(function() { 
    var timer; 
    $("#searchMe").keyup(function() { 
    clearTimeout(timer); 
    var ms = 200; // milliseconds 
    var val = this.value; 
    timer = setTimeout(function() { 
     lookup(val); 
    }, ms); 
    }); 
}); 
+1

Muchas gracias por esto Josh. algunas cosas nuevas que no he visto! – willdanceforfun

+0

trabajó una delicia. – willdanceforfun

+1

Gracias una tonelada. Trabajado como un encanto. –

1

1 en psuedocode:

OnKeyPress() 
    txt = getTxt 
    sleep(200) 
    newTxt = getTxt 
    if (txt == newTxt) // nothing has been typed so do something 
     run my thing 
3

que realmente debería considerar el uso del plugin de jQuery autocomplete. Creo que este complemento es muy útil y ya hace lo que necesita. Mire particularmente el retraso option, que puede personalizar para cambiar cuánto tiempo espera el complemento después de una pulsación de tecla para ejecutarse.

+0

aplausos, yo usaría un plugin, pensé que era una cosa tan pequeña que hacer y tenía la mitad del código en su lugar, ya no había mucho po int para instalar uno. ¡gracias de todos modos! – willdanceforfun

+0

++ solo puede cambiar su avatar? Cuando veo sus respuestas en cualquier lugar, siento que este sitio web está relacionado con médicos ':-)' ..! * (eso es debido a su ropa blanca) * – Shafizadeh

-1

he encontrado el mejor éxito al colocar el evento de pulsación de tecla, keydown y keyup entradas. Safari/Firefox/IE parecen manejar presionar teclas especiales (borrar, retroceder, etc.) de una manera un poco diferente, pero el uso de todos los eventos juntos parece cubrirlo. La única forma de que funcione la ejecución de todos los eventos es utilizar setTimeout para que cuando todos disparen solo restablezca el temporizador y, en última instancia, la devolución de llamada solo se ejecute una vez.

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); 
}); 
1

éste es feliz

$(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);  
    }  
}); 
}); 
4

Usted puede estar interesado en mi bindDelayed jQuery mini-plug-in. Es:

  • Le permite especificar un retraso antes de dar comienzo al pedido
  • cancela automáticamente las solicitudes previas que estaban programados para apagarse
  • cancela automáticamente cualquier peticiones XHR en el aire que estaban en curso en el momento hacer su solicitud
  • invoca Sólo su devolución de llamada para la última solicitud
    • Si el usuario escribe "s", espera el tiempo suficiente para que la solicitud para salir, y luego los tipos "a", y la respuesta de "s "vuelve ser antes de la respuesta para "sa" no tendrás que lidiar con eso.

La respuesta a la pregunta original usando bindDelayed se vería así:

// 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'); 

En caso de que mi sitio está desactivado, aquí está el código del plugin para el desbordamiento de pila posteridad:

(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); 
+0

¡Es un mini plugin genial! ¡Gracias por escribir y compartir ese @Phrogz! – willdanceforfun

Cuestiones relacionadas