Pinchar el teclado en Javascript
Este fragmento HTML pincha los 3 eventos de teclado de un control de tipo textarea
:
Además pretende comparar las propiedades disponibles
Según el navegador utilizado.
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Pinchando teclado en un textarea</title> <script type="text/javascript"> var burbuja = false; // si true la burbuja está en marcha keydown-press-up ... function valorGrupo(nombreGrupo) { var grupo = document.getElementsByName(nombreGrupo); var valor = null; for (var i = 0; i < grupo.length; i++) { if (grupo[i].checked) { valor = grupo[i].value; break; } } return valor; } function logEvent(EVENTO, skeyCode, swhich, scharCode, skey) { var info = document.getElementById("infoEvento"); //display var cadena = EVENTO + "==>skeyCode:" + skeyCode + " swhich:" + swhich + " scharCode:" + scharCode + "skey:" + skey + "<br>" if (valorGrupo("limpiar") == "dejar") if (burbuja) info.innerHTML += "<hr>" + cadena else info.innerHTML += cadena else //LIMPIAR if (burbuja) info.innerHTML = cadena else info.innerHTML += cadena } function onKeyDown(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event burbuja = true; logEvent("onKeyDown", e.keyCode, e.which, e.charCode, e.key); burbuja = false; } function onKeyPress(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event logEvent("onKeyPress", e.keyCode, e.which, e.charCode, e.key); } function onKeyUp(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event logEvent("onKeyUp", e.keyCode, e.which, e.charCode, e.key); } function manejadores() { document.getElementById('texto').onkeydown = onKeyDown; document.getElementById('texto').onkeypress = onKeyPress; document.getElementById('texto').onkeyup = onKeyUp; } </script> </head> <body onload="manejadores();"> <form> <fieldset> <legend>Pinchando teclado en un textarea</legend> <input type="radio" value="limpiar" name="limpiar" checked>limpiar <input type="radio" value="dejar" name="limpiar">dejar <br> <label for="texto">Comentarios</label> <textarea rows="5" cols="80" name="Texto" id="texto"></textarea> <div id="infoEvento"></div> </br> </fieldset> </form> </body> </html>
Es una herramienta para analizar como se disparan, y de que información disponemos según el navegador utilizado, en cada uno de los tres eventos, y para cada una de las cuatro propiedades estudiadas (keyCode, which, charCode y key).
Banco de pruebas
Para analizar el comportamiento de la burbuja de eventos y de la información que tenemos del mismo en diferentes navegadores, en el textarea:
<textarea rows="5" cols="80" name="Texto" id="texto"></textarea>
Usaremos la secuencia de teclas:
- letra A
- punto .
- tecla [SUPR]
Es decir la secuencia A.[SUPR]
.
Salida en diferentes navegadores y en diferentes sistemas operativos
La secuencia A.[SUPR]
se captura de forma diferente según el navegador utilizado.
Google Chrome en Windows utiliza el mismo motor que el mismo en Google Chrome en Linux, misma observación para Mozilla Firefox, después se incluye captura para Internet Explorer en Windows.
Así se vería el ejemplo usando el navegador Mozilla Firefox en un sistema operativo GNU/Linux:
Donde se aprecian los 3 eventos disparándose, tanto para el código 65 de la letra A, como para los códigos 37 (flecha izquierda) y 46 (SUPR) de las teclas especiales.
Problema a resolver: El carácter punto ‘.’ 46, coincide con la tecla [SUPR].
En cambio en Google Chrome y también en GNU/Linux esto es lo que se aprecia:
- Solo se dispara keypress si se trata de la letra A o el punto.
- Pero para códigos de teclas especiales 46 (SUPR) se disparan el evento onKeyDown y el evento onKeyUp, pero no el keypress.
De aquí se desprende que las teclas especiales en Google Chrome, no disparan el evento onKeyPress.
Por lo que, si queremos conseguir limitar los carácteres permitidos en un control, y además limitar las teclas de edición, y sólo permitir las flechas de los cursores, el borrado hacia detrás[Backspace]
y el borrado hacia delante[SUPR]
, deberemos gestionar desde onKeyDown y no desde onKeyPress.
Y por último así se ve en Internet Explorer en Microsoft Windows:
- En este caso Internet Explorer se comporta igual que Chrome y sólo dispara keypress si se trata de la letra ‘A’ o el punto ‘.’, ambos carácteres imprimibles.
- En teclas especiales keyCode = 46 (SUPR) se disparan los eventos onKeyDown y onKeyUp, pero no keypress.
Puesta en común
En la siguiente tabla tenéis el resumen de lo que aquí se ha pretendido analizar:
Si lo estudiamos por eventos:
keyDown
keyPress
keyUp
De donde se desprende que en los eventos keyDown y keyUp tenemos toda la información en la propiedad keyCode. Y el evento keyPress es insuficiente para tratar ciertos aspectos del teclado, pero nos servirá en el siguiente artículo para limitar el conjunto de caracteres permitidos en un control de formulario.
Podéis ver el ejemplo en directo pinchando aquí: Pinchar el teclado en Javascript
Explicación del código
Las funciones utilizadas para capturar los eventos son las siguientes.
En el evento onload de la página, momento en el que estamos seguros de tener disponible todo el DOM de la misma, …
<body onload="manejadores();">
… pinchamos mediante la función manejadores() los tres eventos de teclado:
function manejadores() { document.getElementById('texto').onkeydown = onKeyDown; document.getElementById('texto').onkeypress = onKeyPress; document.getElementById('texto').onkeyup = onKeyUp; }
Estos manejadores simplemente recuperan la información de las 4 propiedades:
- keyCode
- which
- charCode
- key
Y las imprimen en un div cuyo id = ‘infoEvento’:
<div id="infoEvento"></div>
Mediante una función helper:
function logEvent(EVENTO, skeyCode, swhich, scharCode, skey) { var info = document.getElementById("infoEvento"); //display var cadena = EVENTO + "==>skeyCode:" + skeyCode + " swhich:" + swhich + " scharCode:" + scharCode + "skey:" + skey + "<br>" if (valorGrupo("limpiar") == "dejar") if (burbuja) info.innerHTML += "<hr>" + cadena else info.innerHTML += cadena else //LIMPIAR if (burbuja) info.innerHTML = cadena else info.innerHTML += cadena }
Que según se haya seleccionado el radio button limpiar o mantener, irá machacando, o bien concatenando el flujo de eventos, y el valor de las propiedades:
<input type="radio" value="limpiar" name="limpiar" checked>limpiar <input type="radio" value="dejar" name="limpiar">dejar
Para ello utiliza otro helper:
function valorGrupo(nombreGrupo) { var grupo = document.getElementsByName(nombreGrupo); var valor = null; for (var i = 0; i < grupo.length; i++) { if (grupo[i].checked) { valor = grupo[i].value; break; } } return valor; }
Además es necesaria una booleana Global que controle si se trata de un inicio de burbuja, es decir, si se acaba de pulsar (keyDown) la tecla, donde se ACTIVA este flag, se llama a la función logEvent y se vuelve a poner a false. Para que el código condicional siguiente:
if (valorGrupo("limpiar") == "dejar") if (burbuja) info.innerHTML += "<hr>" + cadena else info.innerHTML += cadena else //LIMPIAR if (burbuja) info.innerHTML = cadena else info.innerHTML += cadena
- En el caso “dejar” si es comienzo de burbuja pinta una separación hr, sino concatena
- En caso de “limpiar” si es comienzo de burbuja machaca, sino concatena.
El código de los 3 manejadores de eventos es el siguiente:
function onKeyDown(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event burbuja = true; logEvent("onKeyDown", e.keyCode, e.which, e.charCode, e.key); burbuja = false; } function onKeyPress(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event logEvent("onKeyPress", e.keyCode, e.which, e.charCode, e.key); } function onKeyUp(infoEvento) { var e = infoEvento || window.event; // para salvar las deficiencias de IE=window.event logEvent("onKeyUp", e.keyCode, e.which, e.charCode, e.key); }
En el ejemplo del siguiente artículo, veremos como limitar los caracteres que el usuario puede usar en un control.
Hasta la próxima.