2009-07-03 31 views
26

Estoy trabajando con el campo de texto HTML básico <input type="text"/> con un valor numérico.Prevenir el comportamiento predeterminado en la entrada de texto mientras se presiona la flecha hacia arriba

Estoy agregando el evento de JavaScript keyup para ver cuando el usuario presiona la tecla de flecha hacia arriba (e.which == 38) - luego incremente el valor numérico.

El código funciona bien, pero hay una cosa que me molesta. Tanto Safari/Mac como Firefox/Mac mueven el cursor desde el principio cuando estoy presionando la tecla de flecha hacia arriba. Este es un comportamiento predeterminado para cada campo de texto <input type="text"/> por lo que sé y tiene sentido.

Pero esto no crea un efecto muy estético del cursor al saltar hacia adelante y hacia atrás (después de que se modificó el valor).

El salto al principio ocurre en keydown pero incluso con este conocimiento no puedo evitar que ocurra. He intentado lo siguiente:

input.addEventListener('keydown', function(e) { 
    e.preventDefault(); 
}, false); 

Poner en e.preventDefault()keyup caso no ayuda tampoco.

¿Hay alguna manera de evitar que el cursor se mueva?

Respuesta

27

Para conservar la posición del cursor, haga una copia de seguridad input.selectionStart antes de cambiar el valor.

El problema es que WebKit reacciona a keydown y Opera prefiere keypress, por lo que hay kludge: ambos se manejan y regulan.

var ignoreKey = false; 
var handler = function(e) 
{ 
    if (ignoreKey) 
    { 
     e.preventDefault(); 
     return; 
    } 
    if (e.keyCode == 38 || e.keyCode == 40) 
    { 
     var pos = this.selectionStart; 
     this.value = (e.keyCode == 38?1:-1)+parseInt(this.value,10);   
     this.selectionStart = pos; this.selectionEnd = pos; 

     ignoreKey = true; setTimeout(function(){ignoreKey=false},1); 
     e.preventDefault(); 
    } 
}; 

input.addEventListener('keydown',handler,false); 
input.addEventListener('keypress',handler,false); 
+1

¡Lo rompió! Muchas gracias, es perfecto. :) – riddle

+0

¡Vota por "kludge"! Trabajó para mí, gracias por la respuesta. – NotJay

-1

Probablemente no. En su lugar, debe buscar una solución para mover el cursor de regreso al final del campo donde estaba. El efecto sería el mismo para el usuario ya que es demasiado rápido para ser percibido por un humano.

Busqué en Google y encontré este fragmento de código. No puedo probarlo ahora y se dice que no funciona en IE 6.

textBox.setSelectionRange (textBox.value.length, textBox.value.length);

+1

Gracias. En realidad, la actualización de input.value hará que el cursor retroceda al final. Así que podría detectar la posición del cursor y luego restaurarlo después de realizar el cambio (si está en el medio del número, por ejemplo). Pero todavía estoy buscando una mejor solución, si está disponible. – riddle

0

Probé el código y parece que cancela el evento, pero si no presiona la flecha durante un tiempo muy corto, desencadena el evento de pulsación de tecla y ese evento realmente mueve el cursor. Simplemente use preventDefault() también en el controlador de eventos keypress y debería estar bien.

+0

Desafortunadamente, el evento 'e.preventDefault()' en 'keypress' me impide ingresar nada allí (quiero que las entradas funcionen como en Firebug).Y no resuelve mi problema, al menos en mi navegador: el cursor todavía salta desde el principio. – riddle

13

He descubierto que la mejor solución es sólo para return false; para evitar el default flecha comportamiento de las teclas:

input.addEventListener("keydown", function(e) { 
    if (e.keyCode === 38 || e.keyCode === 40) return false; 
}, false); 
+0

Gracias hombre. La idea es usar el evento de tecla en lugar de la tecla. –

+4

Derecha - la clave es el truco. Tenga en cuenta que devolver false parece detener por completo la propagación del evento, mientras que 'preventDefault()' permitirá que el cuadro de entrada ignore el evento, al tiempo que permite que otros oyentes lo manejen a medida que surge. – CmdrMoozy

+2

@Lukas, su solución funcionó mejor para mí. Sin embargo, estoy llamando 'e.preventDefault();' en lugar de devolver 'false'. Este último no logró congelar el comportamiento de la tecla flecha arriba. Gracias por publicar una solución alterna, más simple. –

4

En realidad, hay un método mejor y más simple para hacer este trabajo.

$('input').bind('keydown', function(e){ 
    if(e.keyCode == '38' || e.keyCode == '40'){ 
     e.preventDefault(); 
    } 
}); 

Sí, es tan fácil!

+0

eres un héroe. gracias – zeeks

+0

gracias, hizo el trabajo –

+0

Me acabas de ahorrar de pasar horas lidiando con este problema, ¡gracias! –

Cuestiones relacionadas