DEV Community

Francisco Quintero 🇨🇴
Francisco Quintero 🇨🇴

Posted on • Originally published at otroespacioblog.wordpress.com

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 Track

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;
Enter fullscreen mode Exit fullscreen mode

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();
  }
});

Enter fullscreen mode Exit fullscreen mode

Vaya diferencia para lograr lo mismo 😀


Este artículo fue publicado primero en mi blog personal, Otro Espacio Blog. Ahí escribo sobre todo lo que aprendo al programar y también sobre temas no relacionados a tecnología.

Discussion (0)