Quiero que cuando se aprieta mucho tiempo una tecla no se escriba varias veces
[...]
cuando se escribe rápido, no se escribe todo. como puedo mejorarlo?
En vez de medir tiempos, tenemos que saber cuándo el usuario está repitiendo una tecla. Para ello, usamos la propiedad KeyboardEvent.repeat, que devuelve true cuando no se levantó la tecla y se mantuvo presionada, generando un sucesivo tecleo.
var texto=document.getElementById("texto");
texto.addEventListener('keydown', function(keyboardEvent) {
//Si se está repitiendo, ignorar
if (keyboardEvent.repeat)
keyboardEvent.preventDefault();
});
<textarea id="texto" style="width: 100%; height: 8em"></textarea>
Adaptado a diferentes versiones de Internet Explorer
IE no deja de ser la excepción a la regla (-¿qué raro, no?). En este caso, cuando asociamos el evento con addEventListener()
, IE siempre devuelve KeyboardEvent.repeat == false
. En cambio, devuelve el valor correcto cuando se utiliza attachEvent...
Pero hay más, attachEvent pasó a ser obsoleto a partir de IE11, con lo cual quedó sin una solución directa. Entonces, para solucionar este segundo problema, usamos la etiqueta meta para el modo de legado X-UA-Compatible: <meta http-equiv="X-UA-Compatible" content="IE=10" />
.
Y, de yapa, agregamos algunas excepciones para teclas que normalmente se quiere dejar repetir (backspace, del, flechas, home, etc).
<!DOCTYPE html>
<html>
<head>
<title>Evitar caracteres repetidos</title>
<meta http-equiv="X-UA-Compatible" content="IE=10" />
<style>
#texto {
width: 100%;
height: 8em;
}
</style>
</head>
<body>
<textarea id="texto" placeholder="Mantenga presionada una tecla"></textarea>
<script language="javascript">
var texto = document.getElementById("texto"),
excepcionesTeclas = [
8,9,13,46, //backspace tab enter del
33,34,35,36, //PgUp/Dn home end
37,38,39,40 //flechas
];
//attachEvent para IE, addEventListener para el resto
if (texto.attachEvent) texto.attachEvent('onkeydown', noRepetirTeclas);
else texto.addEventListener('keydown', noRepetirTeclas);
function noRepetirTeclas(keyboardEvent) {
//obtener .repeat según navegador
var repeat;
if (window.event && 'repeat' in window.event)
repeat = window.event.repeat;
else
repeat = keyboardEvent.repeat;
//Si se está repitiendo, ignorar
// excepcionesTeclas deja repetir backspace, flechas, etc.
if (repeat && !~excepcionesTeclas.indexOf(keyboardEvent.keyCode)) {
if (keyboardEvent.preventDefault)
keyboardEvent.preventDefault();
else if ('returnValue' in keyboardEvent)
keyboardEvent.returnValue = false; //IE
else
return false; //IE viejo
}
}
</script>
</body>
</html>
* Para IE 8- es necesario usar el Polyfill de Array.prototype.IndexOf().
Demo subida a un hosting gratuito