2009-07-03 5 views
26

Je travaille avec le champ de texte de base HTML <input type="text"/> avec une valeur numérique.Prévenir le comportement par défaut dans la saisie de texte tout en appuyant sur la flèche vers le haut

J'ajoute l'événement JavaScript keyup pour voir quand l'utilisateur appuie sur la touche fléchée vers le haut (e.which == 38) - alors j'incrémente la valeur numérique.

Le code fonctionne bien, mais il y a une chose qui me dérange. Safari/Mac et Firefox/Mac déplacent le curseur au tout début lorsque j'appuie sur la touche fléchée vers le haut. C'est un comportement par défaut pour chaque champ de texte <input type="text"/> autant que je sache et cela a du sens. Mais cela ne crée pas un effet très esthétique du curseur qui saute en arrière et en avant (après que la valeur ait été modifiée).

Le saut au début se passe sur keydown mais même avec cette connaissance je ne suis pas capable d'empêcher cela. J'ai essayé les éléments suivants:

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

Mise en e.preventDefault()keyup événement ne contribue pas non plus.

Y a-t-il un moyen d'empêcher le déplacement du curseur?

Répondre

27

Pour conserver la position du curseur, sauvegardez input.selectionStart avant de modifier la valeur.

Le problème est que WebKit réagit à keydown et Opera préfère keypress, donc il y a kludge: les deux sont gérés et limités.

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

Busted it! Merci beaucoup, c'est parfait. :) – riddle

+0

Jusqu'à voter pour "kludge"! A travaillé pour moi, merci pour la réponse. – NotJay

-1

Probablement pas. Vous devriez plutôt chercher une solution pour ramener le curseur à la fin du champ où il se trouvait. L'effet serait le même pour l'utilisateur puisqu'il est trop rapide pour être perçu par un humain.

J'ai fait une recherche sur google et trouvé ce morceau de code. Je ne peux pas le tester maintenant et il est dit de ne pas fonctionner sur IE 6.

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

+1

Merci. La mise à jour de input.value entraînera le retour du curseur à la fin. Donc, je pourrais détecter la position du curseur, puis le restaurer après le changement (si c'est au milieu du numéro, par exemple). Mais je suis toujours à la recherche d'une meilleure solution, si elle est disponible. – riddle

0

J'ai testé le code et il semble qu'il annule l'événement mais si vous n'appuyez pas sur la flèche pendant très peu de temps - il déclenche l'événement keypress et cet événement déplace réellement le curseur. Utilisez simplement preventDefault() également dans le gestionnaire d'événements keypress et ça devrait aller.

+0

Malheureusement, 'e.preventDefault()' dans l'événement 'keypress' m'empêche d'y entrer quelque chose (je veux que les entrées fonctionnent comme dans Firebug).Et cela ne résout pas mon problème, au moins dans mon navigateur - le curseur saute toujours au tout début. – riddle

13

J'ai trouvé qu'une meilleure solution est juste return false; pour empêcher le comportement flèche par défaut:

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

Merci l'homme. L'idée est d'utiliser l'événement keydown au lieu du keyup. –

+4

Droite - le clavier est l'astuce. Notez que return false semble arrêter complètement la propagation de l'événement, alors que preventDefault() 'laissera la boîte de saisie ignorer l'événement, tout en permettant aux autres écouteurs de le gérer au fur et à mesure qu'il éclatera. – CmdrMoozy

+2

@Lukas, votre solution a fonctionné le mieux pour moi. Cependant, j'appelle 'e.preventDefault();' au lieu de retourner 'false'. Ce dernier n'a pas réussi à geler le comportement de la touche fléchée vers le haut. Merci d'avoir posté une alternative, une solution plus simple. –

4

En fait, il y a une meilleure et plus simple méthode pour faire ce travail.

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

Oui, c'est si facile!

+0

vous êtes un héros. merci – zeeks

+0

merci, il a fait le travail –

+0

Vous venez de me sauver de passer des heures à traiter ce problème, merci! –

Questions connexes