JavaScript y el DOM: keyDown vs keyPress

Formularios. Qué sería de nuestro software web sin formularios. La majestuosa forma de permitir a los usuarios de un sistema ingresar información.

En realidad los formularios son un dolor de cabeza. Entre menos campos tengan mejor pero hay situaciones donde el mínimo de campos es muchos campos. Un ejemplo de eso es aplicaciones del sector salud donde hay que tomar muchos datos de un paciente.

Para disminuir el impacto de digitar un formulario tan extenso se busca ayuda de expertos en UX y aún así, por debajo de cuerda, hay muchos campos en un solo formulario.

Solo ingresar números

Un caso común de formularios es que determinados campos solo permitan ingresar valores numéricos y no letras del alfabeto. En primera instancia se pensaría que el campo tipo número que trajo consigo HTML5 bastaría, pero no.

Dicho tipo de campo permite que se escriban letras. Su funcionalidad es más orientada al mundo móvil donde en un celular, un campo de tipo número, abre el teclado numérico y no el alfanumérico.

También está el atributo pattern para indicar una expresión regular, sin embargo, hasta donde recuerdo(no lo he vuelto a probar) esta solución se queda corta.

Finalmente, las soluciones más óptimas están dadas por controlar que se ingresa en el campo(s) y prevenir que se ingrese usando un event listener.

Aquí es donde el asunto se pone interesante.

keyDown, keyUp, keyPress

Los anteriores son eventos que se disparan cuando pasa algo en el teclado del usuario. Estos mismos sirven cuando se quiere prevenir que se ingrese texto en el campo del formulario.

Hace un par de años implementé una solución de este tipo usando jQuery y capturando el evento keydown y evitando que se ingresara texto sino era número o alguna de las teclas especiales como CTRL o SHIFT.

La semana pasada, en un proyecto más recién, me tocó implementar algo similar. Lo que hice fue buscar la implementación en el proyecto viejo, sin embargo solo me fijé en la parte interna del manejador de eventos y no en el evento que estaba capturando. En esta nueva implementación usé keypress y ahí vino una complicación.

Pasa que keydown y keypress varian en un atributo.

Cada tecla tiene un código único que la diferencia de las demás. En el caso de keypress este valor viene el atributo charCode y en keydown viene en keyCode. Y resulta que no todas las teclas devuelven un valor para charCode y la implementación fallaba.

Cuando analicé, busqué y probé, me di cuenta la diferencia entre los dos tipos de evento. En la primera implementación estaba usando keydown y en la más reciente keypress. Cuando cambié, todo funcionó como se esperaba.

Y entonces, ¿qué uso?

Hoy en día, el uso de keypress es desaconsejado por MDN ya que está depreciado y debería cambiarse por keydown.

Bonus

Resulta que mientras redactaba este artículo y leía la documentación de los dos eventos, encontré una forma aún más sencilla de impedir el ingreso de texto en campos dispuestos para solo números. Es así según MDN:

function numbersOnly(event) {
return event.charCode === 0 || /\d/.test(String.fromCharCode(event.charCode));
}

const input = document.querySelector('input');

input.onkeypress = numbersOnly;

Bastante sencilla si se compara con mi implementación la cual usa jQuery:

$('form').on('keydown', '.only-numbers', function(e) {
if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
(e.keyCode == 65 && e.ctrlKey === true) ||
(e.keyCode == 67 && e.ctrlKey === true) ||
(e.keyCode == 88 && e.ctrlKey === true) ||
(e.keyCode >= 35 && e.keyCode <= 39)) {
return;
}

if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
});

Vaya diferencia para lograr lo mismo 😀

Autor: cesc1989

Ingeniero de Sistemas que le gusta escribir y compartir sobre recursos que considera útiles, además que le gusta leer manga y ver anime.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios .