septiembre 28, 2009

Technical Reminder (20090928)

Problema: Evitar que un elemento en un documento HTML capture todos los eventos que recibe, estando el evento definido como disparador de una secuencia de funciones JavaScript.

Contexto: Para controlar la forma en la que un usuario interactúa con elementos del documento HTML, es posible que se necesite validar e incluso deshacer la acción que el usuario acaba de efectuar. Si el intervalo entre eventos es muy corto, puede que no se procesen en el orden esperado y alguna de las acciones a deshacer llegue a término por el flujo básico.
Por ejemplo, si se desea implementar un teclado en pantalla, es necesario deshacer cada ingreso de un caracter efectuado desde la entrada de teclado (escuchando atentamente al evento keyup o keydown sobre el elemento input de la contraseña). Es posible (se verificó en pruebas) que al ingresar una gran cantidad de caracteres durante un corto intervalo de tiempo, el motor JS del navegador no procese correctamente la secuencia, continúe capturando los eventos y no retorne correctamente al valor anterior del campo (usando la función setTimeout, por ejemplo).

Solución: La opción más sencilla es la más fácil. Fijar el atributo disabled en true (form.field.disabled = true;) como primer paso en la secuencia a seguir cuando se detecta el evento keydown/keyup, evita que se capturen eventos posteriores, al menos hasta que termine la secuencia y se reestablezca el estado del elemento. En mi caso, incluye una notificación al usuario usando el viejo alert("Use el teclado gráfico") que lo detiene en su empeño al escribir :-)

PD. A quien crea que una implementación de este estilo está lejos de aquel principio "die gracefully", puede decirse a sí mismo que confunde la naturaleza del mismo. Es posible si el diseño y la arquitectura son los adecuados... en el ejemplo, es posible ingresar la contraseña, pero el formulario no debería ser procesado e incluso, el mensaje POST no debería ser enviado (restriccción impuesta al usuario por su seguridad).

En fin,... bis bald!!!

No hay comentarios.: