33 votes

Événement retardé idiomatique de jQuery (uniquement après une courte pause dans la frappe) ? (par exemple, timewatch/typewatch/keywatch)

Voici un peu de jQuery pour une boîte de recherche qui, je pense, est en fait un anti-modèle, et je suis sûr qu'il y a une bien meilleure solution pour cela, vers laquelle j'aimerais bien être dirigé :

Je vais le décrire dans les commentaires puis donner le code, car les commentaires peuvent être plus clairs et plus simples que le code :

  • // mettre en place un appel de fonction lors de l'appui sur le clavier.
  • // L'appel de fonction a un délai avant que l'événement principal ne se produise.
  • // Lorsque la fonction keypress est appelée, efface tous les événements précédemment mis en file d'attente et en crée un nouveau au taux de retard standard.
  • // Utilisez un global pour stocker le pointeur setTimeout.
  • // effacer les pointeurs préexistants.
  • // Commence un nouveau délai.

Le code :

                // set up a filter function call on keypress.
                $('#supplier-select-filter').keypress(function (){
                    // Currently, resets a delay on an eventual filtering action every keypress.
                    filterSuppliers(.3, this);
                });

                // Delayed filter that kills all previous filter request.
                function filterSuppliers(delay, inputbox){
                    if(undefined != typeof(document.global_filter_trigger)){
                        clearTimeout(document.global_filter_trigger);
                        // clearTimeout any pre-existing pointers.
                    }
                    // Use a global to store the setTimeout pointer.
                    document.global_filter_trigger = setTimeout(function (){
                        var mask = $(inputbox).val();
                        $('#user_id').load("supplier.php?action=ajax_getsuppliers_html&mask="+escape(mask)); 
                    }, 1000*delay); 
                    // Finally, after delay is reached, display the filter results.             
                }

Les problèmes :

Sur un champ de saisie où un terme de recherche peut comporter 10 caractères en moyenne, cela représente 10 appels à setTimeout en une demi-seconde, ce qui semble être lourd pour le processeur, et dans mes tests, cela cause des problèmes de performance notables, donc j'espère qu'il y a une alternative plus propre ?

.load() est plus simple que de prendre du JSON et de générer du html à partir du json, mais peut-être existe-t-il un meilleur outil ?

.keypress() ne semble pas toujours se déclencher sur des choses comme la suppression du retour arrière et d'autres éléments essentiels, alors peut-être que l'utilisation de keypress() sur cette zone de saisie n'est pas l'idéal ?

96voto

CMS Points 315406

J'utilise fréquemment l'approche suivante, une simple fonction pour exécuter un callback, après que l'utilisateur ait arrêté de taper pendant une durée déterminée: :

$(selector).keyup(function () {
  typewatch(function () {
    // executed only 500 ms after the last keyup event.
  }, 500);
});

Mise en œuvre :

var typewatch = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  }  
})();

Je pense que cette approche est très simple, et qu'elle n'implique aucune variable globale.

Pour des utilisations plus sophistiquées, jetez un coup d'oeil à jQuery Plugin TypeWatch .

3voto

Rob Cowie Points 10471

Jetez un coup d'œil à l'excellent Événement de changement de texte plugin de Zurb, fournisseurs de produits jQuery de la plus haute qualité.

0voto

HarshSharma Points 122

C'est une meilleure façon de le faire, sans utiliser le plugin :

var timeout;
$('input[type=text]').keypress(function() {
if(timeout) {
    clearTimeout(timeout);
    timeout = null;
}

timeout = setTimeout(myFunction, 5000)
})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X