2010-02-08 4 views
33

Aquí es un poco de jQuery para un cuadro de búsqueda que espero es en realidad un anti patrón, y estoy seguro de que es una solución mucho mejor para que me encantaría hacia la boca:Idiomatic jQuery evento retrasado (solo después de una breve pausa al escribir)? (También conocido como TimeWatch/typewatch/keywatch)

I lo describirá en comentarios y luego solo ingrese el código, ya que los comentarios pueden ser más claros y simples que el código:

  • // configurar una llamada de función al presionar las teclas.
  • // la llamada a la función tiene un retraso antes de que ocurra el evento principal.
  • // Cuando se invoca la función de pulsación de teclas, borre todos los eventos previamente en cola y cree uno nuevo con la tasa de retardo estándar.
  • // Usa un global para almacenar el puntero setTimeout.
  • // clearTimeout cualquier puntero preexistente.
  • // Comienza un nuevo retraso.

El Código:

   // 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.    
       } 

Los problemas:

En un cuadro de entrada, donde un término de búsqueda puede constar de 10 caracteres en promedio, que es 10 llamadas a setTimeout en un medio segundo, que parece ser un procesador pesado, y en mis pruebas está causando algunos problemas de rendimiento notables, ¿así que con suerte hay una alternativa más limpia?

.load() es más simple que tomar JSON y luego generar html desde json, pero ¿tal vez hay una herramienta mejor?

.keypress() no parece activarse siempre en cosas como la eliminación de retroceso y otros elementos esenciales, por lo que quizás el uso de la tecla() en este cuadro de entrada no sea el ideal.

+0

Pequeño comentario - "10 llamadas a setTimeout en un medio segundo" no es realmente un problema de rendimiento, no lo haría Preocúpate por eso. –

Respuesta

96

Suelo utilizar el siguiente enfoque, una simple función para ejecutar una devolución de llamada, después de que el usuario ha dejado de escribir para un período de tiempo especificado ::

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

Implementación:

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

I Creo que este enfoque es muy simple y no implica ninguna variable global.

Para usos más sofisticados, eche un vistazo a jQuery TypeWatch Plugin.

+10

También recomiendo comprobar si current_value! == valor_de_ventario en la función de devolución de llamada, antes de obtener datos nuevos a través de AJAX. Podría ser que el usuario simplemente esté usando las teclas de flecha, etc. –

+0

Huh.Se ve bien y limpio, aunque realmente no entiendo cómo el puntero setTimeout puede ser no global y aún acceder más tarde como una var estática en php, aunque estoy seguro de que funciona. ¿Cómo se llama eso permite eso? – Kzqai

+1

@Tchalvak: la variable permanece en el ámbito de la función devuelta incluso si la primera función ha finalizado su ejecución, porque se crea ** un cierre **, esta es una de las funciones más potentes de JavaScript ... Eche un vistazo a este artículo: http://www.jibbering.com/faq/faq_notes/closures.html – CMS

3

Eche un vistazo al excelente plugin Text Change Event de Zurb, proveedores de los productos jQuery de la más alta calidad.

+0

El OP quería una devolución de llamada después de una pausa al escribir, que no es lo que hace el complemento de Evento de cambio de texto. –

+0

Es posible ayudar al OP a implementar la funcionalidad que desea. Da _ proporciona_ un mejor evento para activar la devolución de llamada demorada. No soy el único en esta página que sugiere que la devolución de llamada probablemente no se invoque si el contenido de la entrada no ha cambiado. –

0

Ésta es una más buena manera de hacerlo, sin necesidad de utilizar el plugin:

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

timeout = setTimeout(myFunction, 5000) 
}) 
Cuestiones relacionadas