Wednesday 3 September 2008

Eventos de teclado con Javascript: onKeyPress, onKeyUp y KeyCode

¿Has necesitado alguna vez controlar con javascript cuándo el visitante de tu web aprieta INTRO cuando está dentro de algún "input" tipo "text", por ejemplo para ejecutar un "submit" del formulario desde javascript en ese momento? La solución es sencilla y pasa por utilizar el evento onKeyPress y la propiedad KeyCode.

Cross-browser y cross-time

Antes que nada, hay que advertir que el mecanismo de hacer esta "captura de
pulsaciones de teclado" ha ido evolucionando al mismo ritmo que han ido evolucionando los diferentes navegadores. Es decir, que si queremos tener un script cross-browser (funcional en "todos" los navegadores), hay que ir con cuidadito y posiblemente el script que utilicemos hoy de aquí a 2 años ya no funcionará en los navegadores más modernos. Creo que es necesario advertirlo porque si uno busca este tema por internet encontrará mil y una soluciones no coincidentes y con resultados distintos. Así que mi consejo es doble: fijaros en la fecha del post y en todo caso, haced vosotros mismos unas cuantas pruebas del script que vayais a implementar ;)

Código HTML


1  <html>
2       <h3>Ejemplo de capturar la pulsacion de INTRO en una caja de texto</h3>
3       <p>Danos tu email:
4       <input type='text' id='email' 
5            onkeypress="javascript:if (getKeyCode(event)==13) alert('Gracias.')" />
6       </p>
7       <script>
8            function getKeyCode(e){
9                 e= (window.event)? event : e;
10                 intKey = (e.keyCode)? e.keyCode: e.charCode;
11                 return intKey;
12            }
13       </script>
14  </html>
Podeis comprobar el funcionamiento de este ejemplo aqui.

Yo he probado que funciona en IE6, IE7, FF2 y FF3, estando a Septiembre de 2008. No puedo comprobarlo en otros navegadores porque no tengo más instalados, pero si alguien lo hace, por favor, comenta aquí tu resultado ;)

Nota: en vuestros comentarios leo que también funciona sin problemas en Opera 9.62

Nota: la sintaxis utilizada en la línea e= (window.event)?event:e; se llama asignación abreviada. Si no las ha utilizado nunca, lee esta breve explicación que acabo de postear.

Ampliación 04-02-2009: onKeyUp

La semana pasada decubrí que se puede usar onKeyUp en lugar de onKeyPress, y ciertamente con mejores resultados. Voy a explicar brevemente la diferencia porque creo que a más de uno le va a interesar.


Obviamente ya sabemos todos los que hemos programado en otros lenguajes que contienen eventos que ambos son muy parecidos. Pero en concreto, me gustó más el resultado obtenido con onKeyUp porque detecta "mejor" el momento en el que los valores de la caja de texto cambian! He rehecho la página de ejemplo para que podáis probar la diferencia.


En donde se aprecia muy bien la diferencia es haciendo lo siguiente: escribimos algo de texto en la caja (probadlo en ambas cajas para ver la diferencia) y el texto se irá "copiando" automaticamente en una etiqueta span que tengamos debajo. Hasta aquí ambos eventos funcionan "aparentemente" igual: cada vez que escribimos una letra, se dispara el evento y replica el contenido de la caja en el span.

Sin embargo, una vez tengais escrito algo de texto, seleccionad parte del texto y pulsad una tecla cualquiera y veréis la diferencia entre ambos eventos: onKeyPress no actualiza el contenido del span, pero onKeyUp sí lo hace!. es decir, sí lo hace, pero solamente si luego seguimos pulsando más teclas, pero no lo hace inmediatamente :(



Jejeje, no me preguntéis el porqué ocurre eso, pero creo que nos es útil saberlo, verdad?! Yo lo descubrí proque estaba haciendo una especie de calculadora de precios: necesitaba que en el span saliera automaticamente el precio con IVA de un precio que yo introducía en un input, y necesitaba que funcionara sincronizadamente (como sucede usando onKeyUp).

15 comments:

  1. GRACIAS ME SIRVIO DE AYUDA....

    Raúl ....Lima - Perú

    ReplyDelete
  2. Hola a todos,
    Este script tambien funciona en Opera 9.62
    Saludos
    Pablo
    http://www.juegostotal.com.ar

    ReplyDelete
  3. No funciona en Firefox..3.x

    ReplyDelete
  4. @anónimo: lo acabo de probar en FireFox 3.0.10, tanto en Ubuntu como en winXP, y funciona perfectamente.

    ¿puedes ser más explícito en cuanto a tu configuración? así podría replicar el "error" si lo hay y corregirlo. Por cierto, ¿qué es lo que no funciona de los tres ejemplos? ¿ninguno?

    ReplyDelete
  5. en OPERA, estoy probando el keyUP funciona bien, salvo para cuando tenemos las teclas mayusculas activada, pero bueno, el error es que cuando esta en mayusculas activadas, el keyup no responde. alguna idea... ?¿

    ReplyDelete
  6. Si funciona en Firefox 3.5.5, gracias por el artículo

    ReplyDelete
  7. Maestro, funcionara este codigo en HTML5 en Android o en Iphone?, mi pregunta es válida, dado que la web no es solo unix, windows y mac, que pasa si el usuario entra con un Web Palm OS o con Symbian.

    Saludos.

    ReplyDelete
  8. Hola Norant, tienes mucha razón en lo que dices, y ya avisé de ello en mi primer párrafo del artículo (Cross-browser y cross-time), advirtiendo que estas cosas varían en el tiempo, simplemente porque los SOs y los navegadores evolucionan, e incluso el HTML y supongo que algún día incluso el javascript ;)

    De todas formas, basándome en suposiciones -es decir- sin haber hecho pruebas aún, me imagino que el factor relevante es el NAVEGADOR, no tanto el sistema operativo. Aunque sé que éste también influye: yo he llegado a notar diferencias de interpretación de mis diseños web entre FF sobre winXP y FF sobre Linux :|

    Supongo que en estas cuestiones, solo el testeo más o menos exhaustivo es capaz de alumbrar algo de verdad. Es por esa razón que cada vez me siento más a gusto programando javascript en base a un framework tipo jQuery, que con total seguridad será más "multi-plataforma" que el javascript que yo pueda escribir ;)

    Saludos amigo, y gracias por tu comentario!
    SERGI

    ReplyDelete
  9. _ Tienes razón, está en el primer parrafo, el desarrollo web es geométrico, y javascript toma en este punto un papel preponderante, ahora en móviles interactua con el sistema operativo como Web Palm OS, se crean bases de datos en javascript

    http://webkit.org/blog/126/webkit-does-html5-client-side-database-storage/

    el motivo es claro, velocidad, hardware y batería, aplicaciones drag and drop, Jquery es un framework potente, pero he tenido problemas con el trabajando en diferentes navegadores, como IE, en las que tienes que añadir lineas de codigo, pero todo esta en evolución y mejora y navegadores obsoletos como ie6 son poco a poco historia.

    Hombre un gusto.

    Saludos.

    ReplyDelete
  10. donde esta la explicacion de window.events

    ReplyDelete
    Replies
    1. Resumidamente: window.events es una tecnología antigua de Microsoft para su IE. Por allá el 2008 -cuando escribí este artículo- todavía seguía dando problemas en otros navegadores como Firefox.

      Amigo, como sabes, lo que se trata es de programar cosas que vean correctamente el máximo de gente posible.

      En este sentido, desde hace ya varios años, yo aposté por la librería de javascript jQuery que se encarga de garantizar que tu código funcione en el máximo número de navegadores posibles a la vez que te proporciona una interfaz de usar muuuuucho más sencilla y potente que la de Javascript, además de numerosos plugins, etc etc etc.

      Delete
  11. This comment has been removed by the author.

    ReplyDelete
  12. Maestro me a servido tu post. a las 5 de la mañana seguia utilizando onkeypres y con malos resultados hasta que lei tu post.
    Mil Gracias por compartir tu sabiduria con el mundo

    ReplyDelete