2009-10-14 19 views
6

He creado una búsqueda ajax estilo de Facebook para mi sitio en el que a medida que escribe en él aparecerá el resultado en una bonita lista su búsqueda.Facebook Estilo de búsqueda AJAX

$("#s").keyup(function() { 
    var searchbox = $(this).val(); 
    var dataString = 's='+ searchbox; 
    if(searchbox!='') { 
     $.ajax({ 
      type: "POST", 
      url: "/livesearch.php", 
      data: dataString, 
      cache: false, 
      success: function(html){ 
       $("#display").html(html).show(); 
      } 
     }); 
    } else {return false; } 
}); 

$("body").click(function() { 
     $("#display").hide(); 
}); 

El problema con esto es que es un poco ineficaz ya que el usuario escriba una palabra, por ejemplo "el fútbol". Esto llevará a cabo 8 solicitudes al servidor. ¿Cuál sería una forma más efectiva de hacer esto? idealmente, creo que debería almacenar la solicitud durante 1 segundo antes de hacer una búsqueda en lugar de una clave instantánea. pero no es 100% seguro de cómo hacer eso ...

Respuesta

10

el método que se está refiriendo a la que se llama "antirrebote"

por lo general tienen una función "de rebote" en la parte inferior de todos mis guiones

var debounce=function(func, threshold, execAsap) { 
    var timeout; 
    return function debounced() { 
     var obj = this, args = arguments; 
     function delayed() { 
      if (!execAsap) 
       func.apply(obj, args); 
      timeout = null; 
     }; 
     if (timeout) 
      clearTimeout(timeout); 
     else if (execAsap) 
      func.apply(obj, args); 
     timeout = setTimeout(delayed, threshold || 100); 
    }; 
}; 

Y entonces cada vez que hago algo que se beneficiarán de una supresión de rebotes que pueda usar de forma genérica

lo que el código sería re-escrito como

$("#s").keyup(debounce(function() { 
    var searchbox = $(this).val(); 
    var dataString = 's='+ searchbox; 
    if(searchbox!='') { 
     $.ajax({ 
       type: "POST", 
       url: "/livesearch.php", 
       data: dataString, 
       cache: false, 
       success: function(html){ 
         $("#display").html(html).show(); 
       } 
     }); 
    } else {return false; } 
} 
,350 /*determines the delay in ms*/ 
,false /*should it execute on first keyup event, 
     or delay the first event until 
     the value in ms specified above*/ 
)); 
+0

por supuesto, se puede jugar con el valor de retardo para averiguar lo que más le convenga, para mí 350m/s funciona perfectamente .... recordar, la gente escriba bastante rápido, y el tiempo de espera consigue restablecen a 350 ms cada vez que se escribe una letra – ekhaled

+0

Además, sugiero almacenamiento en caché de los resultados, ya sea en JS o w/HTTP - ejemplo: 'deboun [500 ms pausa] CWS [1000 ms pausa] [Retroceso] [Retroceso] [Retroceso] [pausa de 500 ms] ce'. Sin almacenamiento en caché, está enviando 2 solicitudes para 'deboun'. – Piskvor

+0

¡Funciona muy bien! ¡Gracias! – TaylorOtwell

2

Otra opción sería la de comenzar a buscar después de 2/3 caracteres. Esperar 1 segundo antes de hacer todas las solicitudes no me parece bien. También intente enviar menos datos al servidor, lo que también podría acelerar la solicitud y la respuesta.

+0

¿Tiene un ejemplo de código? –

+0

pseudocódigo: var prevChars; if (prevChars.length + 3 <= chars.length) {rebote (...); prevChars = caracteres; } – Piskvor

2

usted podría tener un objeto JSON sentado en algún lugar y en busca de que en lugar de buscar la base de datos varias veces. No traerá demasiado voladizo, siempre y cuando no sea una lista de 1,000 amigos o algo así.

+0

Buen punto - de solicitud previa los más buscados para los artículos (en su caso), la búsqueda sólo si la caché se pierda – Piskvor

Cuestiones relacionadas