Question Comment retarder le gestionnaire .keyup () jusqu'à ce que l'utilisateur arrête de taper?


J'ai un champ de recherche. En ce moment, il cherche tous les keyup. Donc si quelqu'un tape "Windows", il fera une recherche avec AJAX pour chaque key-up: "W", "Wi", "Win", "Wind", "Windo", "Window", "Windows".

Je veux avoir un délai, donc il ne recherche que lorsque l'utilisateur arrête de taper 200 ms.

Il n'y a pas d'option pour cela dans le keyup fonction, et j'ai essayé setTimeout, mais ça n'a pas marché.

Comment puis je faire ça?


526
2017-12-15 18:33


origine


Réponses:


J'utilise cette fonction dans le même but, en exécutant une fonction après que l'utilisateur a cessé de taper pendant un certain temps:

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

Usage:

$('input').keyup(function() {
    delay(function(){
      alert('Time elapsed!');
    }, 1000 );
});

Pour quelque chose de plus sophistiqué, jetez un oeil à la jQuery Typewatch brancher.


930
2017-12-15 18:45



Si vous souhaitez effectuer une recherche après que le type est terminé, utilisez une variable globale pour conserver le délai d'expiration renvoyé par votre setTimout appeler et annuler avec un clearTimeout si cela ne s'est pas encore produit, cela ne déclenchera pas le timeout sauf sur le dernier keyup un événement

var globalTimeout = null;  
$('#id').keyup(function(){
  if(globalTimeout != null) clearTimeout(globalTimeout);  
  globalTimeout =setTimeout(SearchFunc,200);  
}   
function SearchFunc(){  
  globalTimeout = null;  
  //ajax code
}

Ou avec une fonction anonyme:

var globalTimeout = null;  
$('#id').keyup(function() {
  if (globalTimeout != null) {
    clearTimeout(globalTimeout);
  }
  globalTimeout = setTimeout(function() {
    globalTimeout = null;  

    //ajax code

  }, 200);  
}   

50
2017-12-15 18:43



Une autre légère amélioration sur la réponse de CMS. Pour autoriser facilement des retards distincts, vous pouvez utiliser les éléments suivants:

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

Si vous souhaitez réutiliser le même délai, faites-le

var delay = makeDelay(250);
$(selector1).on('keyup', function() {delay(someCallback);});
$(selector2).on('keyup', function() {delay(someCallback);});

Si vous voulez des délais séparés, vous pouvez faire

$(selector1).on('keyup', function() {makeDelay(250)(someCallback);});
$(selector2).on('keyup', function() {makeDelay(250)(someCallback);});

25
2017-10-08 22:27



Vous pourriez aussi regarder underscore.js, qui fournit des méthodes d'utilité comme rebondir:

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

25
2018-02-18 10:06



Basé sur la réponse de CMS, j'ai fait ceci:

Mettez le code ci-dessous après inclure jQuery:

/*
 * delayKeyup
 * http://code.azerti.net/javascript/jquery/delaykeyup.htm
 * Inspired by CMS in this post : http://stackoverflow.com/questions/1909441/jquery-keyup-delay
 * Written by Gaten
 * Exemple : $("#input").delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);
 */
(function ($) {
    $.fn.delayKeyup = function(callback, ms){
        var timer = 0;
        $(this).keyup(function(){                   
            clearTimeout (timer);
            timer = setTimeout(callback, ms);
        });
        return $(this);
    };
})(jQuery);

Et utilisez simplement comme ceci:

$('#input').delayKeyup(function(){ alert("5 secondes passed from the last event keyup."); }, 5000);

Attention: la variable $ (this) dans la fonction passée en paramètre ne correspond pas à l'entrée


13
2018-03-13 14:40



Retarder les appels multi-fonctions à l'aide d'étiquettes

C'est la solution avec laquelle je travaille. Il retardera l'exécution sur N'IMPORTE QUELLE fonction que vous voulez. Il peut s'agir de la requête de recherche de claviers, peut-être du clic rapide sur les boutons précédents ou suivants (qui autrement enverraient une requête multiple si on cliquait rapidement dessus, et ne seraient pas utilisés après tout). Cela utilise un objet global qui stocke chaque heure d'exécution et la compare avec la requête la plus récente.

Le résultat est que seul ce dernier clic / action sera réellement appelé, car ces requêtes sont stockées dans une file d'attente, après l'appel des X millisecondes si aucune autre requête avec le même libellé n'existe dans la file d'attente!

function delay_method(label,callback,time){
    if(typeof window.delayed_methods=="undefined"){window.delayed_methods={};}  
    delayed_methods[label]=Date.now();
    var t=delayed_methods[label];
    setTimeout(function(){ if(delayed_methods[label]!=t){return;}else{  callback();}}, time||500);
  }

Vous pouvez définir votre propre temps de retard (son option, par défaut à 500ms). Et envoyez vos arguments de fonction dans un "mode de fermeture".

Par exemple si vous voulez appeler la fonction ci-dessous:

function send_ajax(id){console.log(id);}

Pour éviter plusieurs demandes send_ajax, vous les retardez en utilisant:

delay_method( "check date", function(){ send_ajax(2); } ,600);

Chaque requête qui utilise l'étiquette "check date" ne sera déclenchée que si aucune autre requête n'est faite dans le délai de 600 millisecondes. Cet argument est facultatif

Indiquer l'indépendance (appel de la même fonction cible) mais exécuter les deux: 

delay_method("check date parallel", function(){send_ajax(2);});
delay_method("check date", function(){send_ajax(2);});

Résultats en appelant la même fonction, mais les retarder indépendamment en raison de leurs étiquettes étant différentes


8
2018-05-28 10:25



Cette fonction étend un peu la fonction de la réponse de Gaten pour récupérer l'élément:

$.fn.delayKeyup = function(callback, ms){
    var timer = 0;
    var el = $(this);
    $(this).keyup(function(){                   
    clearTimeout (timer);
    timer = setTimeout(function(){
        callback(el)
        }, ms);
    });
    return $(this);
};

$('#input').delayKeyup(function(el){
    //alert(el.val());
    // Here I need the input element (value for ajax call) for further process
},1000);

http://jsfiddle.net/Us9bu/2/


6
2017-09-25 10:36



Je suis surpris que personne ne mentionne le problème avec de multiples entrées dans le CMS très bien coupé.

Fondamentalement, vous devez définir une variable de retard individuellement pour chaque entrée. Sinon, si sb met le texte à la première entrée et saute rapidement à l'autre entrée et commence à taper, callback pour le premier HABITUDE être appelé!

Voir le code ci-dessous Je suis venu avec d'autres réponses:

(function($) {
    /**
     * KeyUp with delay event setup
     * 
     * @link http://stackoverflow.com/questions/1909441/jquery-keyup-delay#answer-12581187
     * @param function callback
     * @param int ms
     */
    $.fn.delayKeyup = function(callback, ms){
            $(this).keyup(function( event ){
                var srcEl = event.currentTarget;
                if( srcEl.delayTimer )
                    clearTimeout (srcEl.delayTimer );
                srcEl.delayTimer = setTimeout(function(){ callback( $(srcEl) ); }, ms);
            });

        return $(this);
    };
})(jQuery);

Cette solution conserve la référence setTimeout dans la variable delayTimer d'entrée. Il passe également la référence de l'élément à callback comme suggéré par fazzyx.

Testé dans IE6, 8 (comp - 7), 8 et Opera 12.11.


5
2017-12-17 12:17



Cela a fonctionné pour moi où je retarde l'opération de logique de recherche et vérifie si la valeur est la même que celle entrée dans le champ de texte. Si la valeur est la même alors je vais de l'avant et effectue l'opération pour les données liées à la valeur de recherche.

$('#searchText').on('keyup',function () {
    var searchValue = $(this).val();
    setTimeout(function(){
        if(searchValue == $('#searchText').val() && searchValue != null && searchValue != "") {
           // logic to fetch data based on searchValue
        }
        else if(searchValue == ''){
           // logic to load all the data
        }
    },300);
});

5
2017-08-31 20:48



Fonction de retard pour appeler sur chaque keyup. jQuery 1.7.1 ou plus requis

jQuery.fn.keyupDelay = function( cb, delay ){
  if(delay == null){
    delay = 400;
  }
  var timer = 0;
  return $(this).on('keyup',function(){
    clearTimeout(timer);
    timer = setTimeout( cb , delay );
  });
}

Usage: $('#searchBox').keyupDelay( cb );


4
2018-06-29 11:42



Si quelqu'un aime retarder la même fonction, et sans variable externe, il peut utiliser le script suivant:

function MyFunction() {

    //Delaying the function execute
    if (this.timer) {
        window.clearTimeout(this.timer);
    }
    this.timer = window.setTimeout(function() {

        //Execute the function code here...

    }, 500);
}

3
2018-01-07 10:23