2010-03-21 13 views
5

Tengo un cuadro de texto en una página web, cuyo valor deseo enviar a XMLHttpRequest. Ahora quiero que el usuario simplemente escriba el valor, sin presionar un botón. Pero si solo envío la solicitud en los eventos del teclado, se disparará cada vez que se presione una tecla.Javascript: Procesar cuando el usuario ha dejado de escribir

Así que, básicamente quiero algo liek este

function KeyUpEvent() 
{ 
    if (user is still typing) 
    return; 
    else 
    //do processing 
} 

Sería muy bueno si la solución podría venir de llanura o mootools javascript. No quiero usar ninguna otra biblioteca.

+0

Un temporizador nunca será suficiente. El usuario podría simplemente distraerse o escribir más lento que cualquier momento que elija como tiempo de espera. Mi solución es la única solución razonable y es la forma en que los usuarios esperan interactuar con los campos y no requiere ningún botón. Si no conoce la longitud del valor, no tiene idea de si el usuario ha terminado. Por lo tanto, corre el riesgo de transmitir un valor que el usuario no quería o esperaba y su experiencia simplemente se ve frustrada por su temporizador, no mejorada. En lo que respecta a la experiencia de UI, es mejor que sigas con los escenarios de uso estándar. – nicerobot

Respuesta

9

La forma en que generalmente se hace esto es reiniciando un temporizador en el evento keyup. Algo como esto:

var keyupTimer; 
function keyUpEvent(){ 
    clearTimeout(keyupTimer); 
    keyupTimer = setTimeout(sendInput,1000); // will activate when the user has stopped typing for 1 second 
} 

function sendInput(){ 
    alert("Do AJAX request"); 
} 
+0

te estás olvidando del teclado, ¿y si decidieran comenzar a escribir de nuevo en 30 segundos? su evento todavía dispara –

+1

que no es una respuesta válida, que disparará el evento [número de caracteres escritos] número de veces –

9

Básicamente, desea iniciar un temporizador en KeyUp, y cuando KeyUp se inicia nuevamente, reinicie el temporizador. Cuando el usuario deja de escribir, el temporizador se agota y su solicitud puede ir en ese momento.

Ejemplo:

var timout_id; 

function keyup_handler(event) { 
    if (timout_id) { 
    clearTimeout(timout_id); 
    } 

    timout_id = setTimeout(function(){ 
    alert('sending data: \n' + event.target.value) 
    }, 800); 
} 

Sólo hay que conectar la función a la entrada de la utilización de su método preferido, y sustituir el alert con su acción preferida.

Por supuesto, hay muchas maneras de generalizar este enfoque y hacerlo más reutilizable, etc., pero creo que esto ilustra la idea básica.

2

Nunca se sabe cuando un usuario está realmente "terminado" de escribir. El usuario podría tomarse un descanso estornudable, una pausa de estiramiento o un descanso para tomar café y luego continuar escribiendo.

Sin embargo, si está implementando algo así como un mecanismo de autocompletar, puede configurar un temporizador (consulte window.setTimeout(...)) para ver si el usuario no ha escrito nada en un cierto período de tiempo. Si obtiene otro evento de activación mientras el temporizador se está ejecutando, puede iniciar el temporizador.

-1

Utilice onBlur y tal vez un onKeyDown para comprobar si el usuario presiona la tecla return/enter.

+0

En serio? ¿Votando hacia abajo esto cuando es el único medio real de saber cuándo un usuario termina de escribir? Es decir, abandonaron el campo o presionaron una tecla que indica que quieren enviarla. De lo contrario, no hay forma de saberlo. No es un temporizador porque es posible que simplemente se hayan distraído. – nicerobot

5

siempre uso esta función sencilla de manejar un temporizador, que se dispara una función de devolución de llamada, después de que el usuario ha dejado de escribir durante un período de tiempo especificado:

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

uso (ejemplo, con MooTools):

$('textInput').addEvent('keyup', function(e){ 
    typewatch(function() { 
    // executed only 500 ms after the last keyup event 
    // make Ajax request 
    }, 500); 
}); 

la principal diferencia entre esta solución y soluciones de otras respuestas es que toda la lógica del temporizador está a cargo de la función typewatch sí, el controlador de eventos no se necesita saber un todo sobre el temporizador, simplemente invoca la función. Además, no hay variables globales a tener en cuenta (el ID del temporizador es no almacenado en una variable global).

1
var keyTimer; 
function onKeyUp(){ 
clearTimeout(keyTimer); 
setTimeout(stoppedTyping,1500); 
} 
function stoppedTyping(){ 
// Profit! $$$ 
} 

EDIT: Maldita ninjas

0

escribí un evento jQuery encargo porque utilizo esta lógica mucho:

jQuery.event.special.stoppedtyping = { 
    setup: function(data, namespaces) { 
    jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler); 
    }, 
    teardown: function(namespaces) { 
    jQuery(this).bind('keyup', jQuery.event.special.stoppedtyping.keyuphandler); 
    }, 
    keyuphandler: function(e) { 
    var interval = 1000; 
    var el = this; 

    if (jQuery.data(this, 'checklastkeypress') != null) { 
     clearTimeout(jQuery.data(this, 'checklastkeypress')); 
    } 

    var id = setTimeout(function() { 
     jQuery(el).trigger('stoppedtyping'); 
    }, interval); 
    jQuery.data(this, 'checklastkeypress', id); 
    } 
}; 

Usted puede utilizar de esta manera:

$('input.title').bind('stoppedtyping', function() { 
    // run some ajax save operation 
}); 

Por alguna razón, nunca podría hacer que funcione con .live (...). No estoy seguro de por qué ...

Cuestiones relacionadas