Après un examen attentif, je propose cela comme une solution beaucoup plus propre dans ce fil:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
Le problème:
Voici quelques explications:
Tout d'abord, jetons un œil à l'ordre des événements lorsque vous passez la souris ou tabulez dans un champ.
Nous pouvons enregistrer tous les événements pertinents comme celui-ci:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
Remarque : j'ai changé cette solution pour l'utiliser click
plutôt que mouseup
comme cela se produit plus tard dans le pipeline d'événements et semble causer des problèmes dans Firefox selon le commentaire de @ Jocie
Certains navigateurs tentent de positionner le curseur pendant les événements mouseup
ou click
. Cela est logique, car vous souhaiterez peut-être démarrer le curseur dans une position et le faire glisser pour mettre du texte en surbrillance. Il ne peut pas faire de désignation sur la position du curseur tant que vous n'avez pas levé la souris. Les fonctions qui gèrent focus
sont donc destinées à répondre trop tôt, laissant le navigateur remplacer votre positionnement.
Mais le hic, c'est que nous voulons vraiment gérer l'événement focus. Il nous permet de savoir la première fois que quelqu'un est entré sur le terrain. Après ce point, nous ne voulons pas continuer à remplacer le comportement de sélection des utilisateurs.
La solution:
Au lieu de cela, dans le focus
gestionnaire d'événements, nous pouvons rapidement attacher des écouteurs pour click
(cliquer) etkeyup
événements (tabuler) qui sont sur le point de se déclencher.
Remarque : La saisie d'un événement de tabulation sera en fait déclenchera dans le nouveau champ de saisie, pas le précédent
Nous ne voulons déclencher l'événement qu'une seule fois. Nous pourrions utiliser .one("click keyup)
, mais cela appellerait le gestionnaire d'événements une fois pour chaque type d'événement . Au lieu de cela, dès que la souris ou la touche est enfoncée, nous appelons notre fonction. La première chose que nous ferons est de supprimer les gestionnaires pour les deux. De cette façon, peu importe que nous tabulions ou que nous entrions dans la souris. La fonction devrait s'exécuter exactement une fois.
Remarque : La plupart des navigateurs sélectionnent naturellement tout le texte lors d'un événement de tabulation, mais comme animatedgif l'a souligné , nous voulons toujours gérer l' keyup
événement, sinon lemouseup
événement persistera à chaque fois que nous y tabulerons. Nous écoutons les deux afin de pouvoir tourner hors des auditeurs dès que nous avons traité la sélection.
Maintenant, nous pouvons appeler select()
après que le navigateur a fait sa sélection, donc nous sommes sûrs de remplacer le comportement par défaut.
Enfin, pour une protection supplémentaire, nous pouvons ajouter des espaces de noms d'événements aux fonctions mouseup
et keyup
afin que la .off()
méthode ne supprime aucun autre écouteur qui pourrait être en jeu.
Testé dans IE 10+, FF 28+ et Chrome 35+
Alternativement, si vous souhaitez étendre jQuery avec une fonction appelée once
qui se déclenchera exactement une fois pour un certain nombre d'événements :
$.fn.once = function (events, callback) {
return this.each(function () {
var myCallback = function (e) {
callback.call(this, e);
$(this).off(events, myCallback);
};
$(this).on(events, myCallback);
});
};
Ensuite, vous pouvez simplifier davantage le code comme ceci:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});