2010-03-09 11 views
29

¿Cómo puedo retrasar las acciones entre pulsaciones de teclas en jQuery? Por ejemplo;acciones de retardo entre pulsaciones de teclas en jQuery

que tienen algo como esto

if($(this).val().length > 1){ 
    $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){ 
    if(data.length > 0) { 
     $('#suggestions').show(); 
     $('#autoSuggestionsList').html(data); 
    }else{ 
     $('#suggestions').hide(); 
    } 
}); 
} 

Quiero evitar la publicación de datos si el usuario de forma continua a escribir. Entonces, ¿cómo puedo dar .5 segundos de retraso?

+0

Estoy asumiendo que esto es en una función que se pasa a 'pulsación de tecla()'? – Jeremy

Respuesta

59

Puede utilizar las capacidades de datos de jQuery para hacer esto, algo como esto:

$('#mySearch').keyup(function() { 
    clearTimeout($.data(this, 'timer')); 
    var wait = setTimeout(search, 500); 
    $(this).data('timer', wait); 
}); 

function search() { 
    $.post("stuff.php", {nStr: "" + $('#mySearch').val() + ""}, function(data){ 
    if(data.length > 0) { 
     $('#suggestions').show(); 
     $('#autoSuggestionsList').html(data); 
    }else{ 
     $('#suggestions').hide(); 
    } 
    }); 
} 

La ventaja principal aquí hay variables globales por todo el lugar, y usted podría terminar con esto de una función anónima en el setTimeout si quisieras, simplemente tratando de hacer el ejemplo lo más limpio posible.

10

Todo lo que necesita hacer es envolver su función en un tiempo de espera que se pone a cero cuando el usuario presiona una tecla:

var ref; 
var myfunc = function(){ 
    ref = null; 
    //your code goes here 
}; 
var wrapper = function(){ 
    window.clearTimeout(ref); 
    ref = window.setTimeout(myfunc, 500); 
} 

Después, simplemente invocar "contenedor" en su evento clave.

+0

+1 menos jQuery para una solución simple. – A1rPun

1

Me envuelvo en una función de este modo:

var needsDelay = false; 

    function getSuggestions(var search) 
    { 
    if(!needsDelay) 
    { 
     needsDelay = true; 
     setTimeout("needsDelay = false", 500); 

     if($(this).val().length > 1){ 
      $.post("stuff.php", {nStr: "" + search + ""}, function(data){ 
       if(data.length > 0) { 
        $('#suggestions').show(); 
        $('#autoSuggestionsList').html(data); 
       }else{ 
        $('#suggestions').hide(); 
       } 
      }); 
     } 
    } 


    } 

De esa manera, no importa cuántas veces se hace ping esto, nunca buscará más de cada 500 milisegundos.

+5

¡nunca pase una cuerda a setTimeout! eval es malo (en * la mayoría de los casos) :) usa una función análoga como: 'setTimeout (function() {needsDelay = false;}, 500);' en su lugar. –

+0

Sé que eval es malo, pero aún así soy flojo y pongo declaraciones de evaluación en mi código. Necesito agregar eso a mi lista nazi. No más eval. – thaBadDawg

3

Hay un buen complemento para manejar esto. respuesta jQuery Throttle/Debounce

+0

¿no hay una dependencia jQuery para todo? Tengo que admitir que el nombre "Debounce" evoca una risa cínica. De todos modos, buen descubrimiento. – matrixugly

+0

lodash también tiene métodos [throttle] (https://lodash.com/docs#throttle) y [rebote] (https://lodash.com/docs#debounce) –

2

de Nick es perfecto, pero si maneja primer evento inmediato es crítico entonces creo que podemos hacer:

$(selector).keyup(function(e){ //or another event 

    if($(this).val().length > 1){ 
     if !($.data(this, 'bouncing-locked')) { 

      $.data(this, 'bouncing-locked', true) 

      $.post("stuff.php", {nStr: "" + $(this).val() + ""}, function(data){ 
       if(data.length > 0) { 
        $('#suggestions').show(); 
        $('#autoSuggestionsList').html(data); 
       }else{ 
        $('#suggestions').hide(); 
       } 
      }); 

      self = this 
      setTimeout(function() { 
       $.data(self, 'bouncing-locked', false); 

       //in case the last event matters, be sure not to miss it 
       $(this).trigger("keyup"); // call again the source event 
      }, 500) 
     } 
    } 
}); 
Cuestiones relacionadas