2009-11-06 12 views
3

J'essaie d'implémenter une fonctionnalité similaire à la fonctionnalité autosuggest pour les balises disponibles sous la zone de texte sur ce site en utilisant Jquery. J'essaye de comprendre comment les demandes sont envoyées après quelques frappes et non après chaque frappe. J'utilise un événement 'keyup' pour déclencher la demande sur mon application. J'ai été amené à réaliser que cela peut entraîner trop de hits du serveur et peut affecter les performances.Comment la fonctionnalité AutoSuggest pour les balises dans StackOverflow évite-t-elle d'interroger chaque frappe

Ce serait génial si certains pouvaient expliquer comment je pourrais implémenter le genre de chose que stackOverflow fait en n'ayant pas une requête exécutée sur chaque keyup. J'ai une fonctionnalité similaire dans une de mes applications Windows.

+0

En essayant de ne pas utiliser un plugin. – Sid

Répondre

2
var activity = new ActivityTimer(1000, function() { 
    doSearch(); 
}); 

$("#searchBox").keyup(function(){ activity.reset() }); 

function ActivityTimer(deadline, callback) { 
    var timer = -1; 

    this.reset = function() { 
     this.cancel(); 
     timer = setTimeout(callback, deadline); 
    }; 

    this.cancel = function() { 
     if(timer >= 0) { 
      clearTimeout(timer); 
      timer = -1; 
     } 
    }; 
} 
6

Lorsque l'utilisateur tape un caractère, une minuterie est démarrée avec un intervalle de 1 seconde. Dans l'événement Tick, la recherche est démarrée. Si l'utilisateur tape à nouveau, la minuterie est redémarrée. La recherche n'est donc effectuée que si le clavier est inactif depuis plus d'une seconde.

échantillon court (il est en C#, mais assez facile à suivre):

public partial class Form1 : Form 
{ 
    private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); 

    public Form1() 
    { 
     InitializeComponent(); 

     timer.Interval = 1000; 
     timer.Tick += new EventHandler(timer_Tick); 
    } 

    void timer_Tick(object sender, EventArgs e) 
    { 
     timer.Stop(); 

     // Do search, or what ever you want to do 
     Console.WriteLine("Searching..."); 
    } 

    private void textBox1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (timer.Enabled) 
     { 
      timer.Stop(); 
     } 

     timer.Start(); 
    } 
} 

Je ne suis pas connu en Javascript, mais le anwswer de here vous aider, je pense:

<input name="domain" type="text" id="domain" onKeyUp="javascript:chk_me();"> 

var timer; 
    function chk_me(){ 

     clearTimeout(timer); 
     timer=setTimeout(function validate(){...},1000); 
    } 
+0

Merci Philip. Alors, comment pourrais-je gérer l'horodatage. Aurais-je besoin de quelque chose comme une variable de classe pour maintenir le dernier horodatage. Je suis un débutant avec javascript si je l'utilise tous les jours. Est-il possible sans créer de classes Javascript – Sid

+0

Jetez un oeil à la réponse acceptée dans cette question: http://stackoverflow.com/questions/1381751/onkeyup-javascript-time-delay –

2

la méthode que vous faites référence est appelé « anti-rebond »

J'ai généralement un « Deboun ce » fonction au bas de tous mes scripts

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

Et chaque fois que je fais tout ce qui bénéficiera d'un debounce je peux l'utiliser génériquement

donc votre code serait écrit

$("#search_box").keyup(debounce(function() { 
    //do stuff in this function 
} 
,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*/ 
)); 

voir Facebook Style AJAX Search pour une utilisation similaire ...