2009-10-14 9 views
6

Ho creato una ricerca Ajax in stile Facebook per il mio sito, mentre durante la digitazione verranno visualizzati i risultati in una bella lista sotto la ricerca.Facebook Style AJAX Search

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

Il problema di questo è che è un po 'inefficace come l'utente digita una parola per esempio "calcio". Questo eseguirà 8 richieste al server. Quale sarebbe un modo più efficace per farlo? idealmente penso che dovrebbe archiviare la richiesta per 1 secondo prima di fare una ricerca piuttosto che una chiave istantanea. ma non sicuro al 100% come fare ...

risposta

10

il metodo a cui ti riferisci si chiama "Antirimbalzo"

solito ho una funzione di "rimbalzo" in fondo a tutti i miei script

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

E poi ogni volta che faccio qualcosa che andrà a beneficio da un antirimbalzo posso usarlo genericamente

Così il vostro codice sarebbe essere riscritto come

$("#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

, naturalmente, si può giocare con il valore di ritardo per scoprire cosa vi si addice meglio, per me 350m/s funziona perfettamente .... ricordate, la gente scrive abbastanza veloce, e il timeout ottiene la risistemazione a 350ms ogni volta che una lettera viene digitato – ekhaled

+0

Inoltre, vi suggerisco di caching dei risultati, sia in JS o w/HTTP - ad esempio: 'deboun [500 ms pause] cws [pausa di 1000 ms] [backspace] [backspace] [backspace] [pausa di 500 ms] ce'. Senza la memorizzazione nella cache, stai inviando 2 richieste per 'deboun'. – Piskvor

+0

Funziona alla grande! Grazie! – TaylorOtwell

2

Un'altra opzione sarebbe quella di avviare la ricerca dopo 2/3 caratteri. Aspettare 1 secondo prima di fare ogni richiesta non mi sembra buona. Prova anche a inviare molto meno dati al server che potrebbero rendere più veloce la richiesta e la risposta.

+0

Hai un esempio di codice? –

+0

pseudocodice: var prevChars; if (prevChars.length + 3 <= chars.length) {debounce (...); precChars = caratteri; } – Piskvor

2

Si potrebbe avere un oggetto JSON seduto da qualche parte e cercare quello invece di cercare nel database più volte. Non porterà troppo strapiombo, purché non sia una lista di 1.000 amici o qualcosa del genere.

+0

Buon punto - pre-fetch il più ricercati per gli oggetti (se del caso), la ricerca solo se la cache miss – Piskvor