entrée jquery sélectionner tout sur focus


327

J'utilise ce code pour essayer de sélectionner tout le texte dans le champ lorsqu'un utilisateur se concentre sur le champ. Ce qui se passe, c'est qu'il sélectionne tout pendant une seconde, puis il n'est pas sélectionné et le curseur de frappe est laissé là où j'ai cliqué ...

$("input[type=text]").focus(function() {
   $(this).select();
});

Je veux que tout reste sélectionné.


Quel navigateur, il semble fonctionner correctement pour moi dans FF?
R0MANARMY

8
Chrome = échec pour celui-ci
wowo_999

1
J'utilisais Chrome, mais .click () résout le problème :)
Tim

4
Remarque: La réponse acceptée ici ne résout que la moitié du problème. Cela fait fonctionner la sélection, mais il est difficile de la désélectionner lors des clics suivants. Une meilleure solution peut être trouvée ici: stackoverflow.com/questions/3380458/…
SDC

Réponses:


481

Essayez d'utiliser clickau lieu de focus. Il semble fonctionner à la fois pour la souris et les événements clés (au moins sur Chrome / Mac):

jQuery <version 1.7:

$("input[type='text']").click(function () {
   $(this).select();
});

jQuery version 1.7+:

$("input[type='text']").on("click", function () {
   $(this).select();
});

Voici une démo


62
le problème est que vous ne pouvez plus sélectionner une partie du texte avec la souris, une fois le clic effectué, le texte intégral est sélectionné.
Helin Wang

6
Pas une solution viable pour moi. Cela crée le problème décrit par Wang.
Marquez

1
Il y a une solution ci-dessous par Nianpeng qui fonctionne également avec la sélection de texte de la souris.
Philibert Perusse

4
@AwQiruiGuo $ .fn.on («clic», ..) peut utiliser moins de mémoire et fonctionner pour les éléments enfants ajoutés dynamiquement.
Ricky Boyce

7
Cela ne fonctionne pas pour focaliser un champ lors de la tabulation.
Colin Breame

65

Je pense que ce qui se passe est le suivant:

focus()
   UI tasks related to pre-focus
   callbacks
       select()
   UI tasks related to focus (which unselect again)

Une solution de contournement peut appeler le select () de manière asynchrone, afin qu'il s'exécute complètement après focus ():

$("input[type=text]").focus(function() { 
    var save_this = $(this);
    window.setTimeout (function(){ 
       save_this.select(); 
    },100);
});

3
$ ("input [type = text]"). focus (function () {var save_this = $ (this); window.setTimeout (function () {save_this.select ();}, 100);});
etienne

@etienne: Oh, bon point: la manipulation de thisest un peu inattendue dans de telles étendues. Je vais mettre à jour le code.
Piskvor a quitté le bâtiment

3
une valeur de timeout de 0 semble également correcte, et la fonction "focusin ()" fonctionne également avec cette méthode.
Tanguy

4
oui, vous n'avez même pas besoin de fixer de période. 0 fera l'affaire puisque les délais d'expiration s'exécutent à la fin de la pile d'appels actuelle. cela signifie que les événements de focus et de clic se déclenchent tous, puis votre fonction s'exécute
Joshua Bambrick

1
Le délai d'expiration 0 semble avoir le problème que l'événement «clic» peut se déclencher dans une image ultérieure, désélectionnant à nouveau la boîte. Je trouve que le délai d'attente 10 semble fonctionner assez bien - pas de retard notable, mais plus fiable que 0.
philh

57

Je pense que c'est une meilleure solution. Contrairement à la simple sélection dans un événement onclick, cela n'empêche pas la sélection / modification de texte avec la souris. Il fonctionne avec les principaux moteurs de rendu, notamment IE8.

$('input').on('focus', function (e) {
    $(this)
        .one('mouseup', function () {
            $(this).select();
            return false;
        })
        .select();
});

http://jsfiddle.net/25Mab/9/


4
Cela ne fonctionne que pour les champs existants, voici une mise à jour pour le lier à de nouveaux champs de saisie: jsfiddle.net
adriaan

Parfois, la mise au point peut être donnée sans un clic, et cela le gère bien. Pour cette raison, c'est pour moi la réponse la plus claire - même s'il peut y avoir des auditeurs d'événements qui se balancent chaque fois que l'entrée est focalisée et non pas d'un clic ... bien mieux que setTimeout
ilovett

Cela ne permet pas un deuxième clic dans les entrées numériques pour sélectionner une autre partie du texte avec la souris. La suppression du second select()semble cependant fonctionner.
dperish

Encore mieux avec un supplément$('input[autofocus]').select();
Daniel Bleisteiner

38

Il y a des réponses décentes ici et @ user2072367 est ma préférée, mais elle a un résultat inattendu lorsque vous vous concentrez via l'onglet plutôt que via le clic. (résultat inattendu: pour sélectionner le texte normalement après la mise au point via l'onglet, vous devez cliquer une fois de plus)

Ce violon corrige ce petit bogue et stocke en outre $ (ceci) dans une variable pour éviter la sélection DOM redondante. Vérifiez-le! (:

Testé dans IE> 8

$('input').on('focus', function() {
    var $this = $(this)
        .one('mouseup.mouseupSelect', function() {
            $this.select();
            return false;
        })
        .one('mousedown', function() {
            // compensate for untriggered 'mouseup' caused by focus via tab
            $this.off('mouseup.mouseupSelect');
        })
        .select();
});

2
+1 vos solutions et celles de @ user2072367 sont les plus propres de tout ce fil et j'aurais aimé qu'il y ait un moyen d'obtenir le plus rapidement possible.
KyleMit

1
Fonctionne même si l'utilisateur essaie de sélectionner lui-même tout le texte, bravo.
Vitani

Pour moi, cela ne fonctionne pas sur ie11 sur Windows 8.1. Il fonctionne dans ie11 sur Windows 7 et Windows 10
Lars Thomas Bredland

1
@LarsThomasBredland J'ai juste essayé de gagner 8.1 + ie11 et cela fonctionne comme prévu. Qu'est-ce qui "ne marche pas" pour vous?
animatedgif

Il ne sélectionne simplement rien. (J'ai testé sur un autre win8 et ça fonctionne là-bas - même niveau d'os et même version)
Lars Thomas Bredland

21

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();
    });
});

Démo dans jsFiddle

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); });

événements ciblés

Remarque : j'ai changé cette solution pour l'utiliser clickplutôt que mouseupcomme 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 mouseupou 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 focussont 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 focusgestionnaire 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 mouseupet keyupafin 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 oncequi 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();
    });
});

Démo au violon


Dans Firefox 31 sur Windows, votre code ne sélectionne le texte que sur chaque clic lorsque vous cliquez entre les deux zones de texte
Vitani

1
@Jocie, je ne sais pas pourquoi il alterne, mais il semble que FF gère la sélection de texte dans l' clickévénement qui est plus bas dans le pipeline que mouseup. Étant donné que nous voulons gérer la fin de la sélection le plus tard possible pour nous donner le plus de chances de remplacer le navigateur, utiliser le clic au lieu de la souris devrait faire l'affaire. Testé dans FF, Chrome et IE.
KyleMit

1
Je vous remercie! Enfin une solution qui fonctionne vraiment et dans tous les navigateurs!
Vincent

1
Oui! Cela a fonctionné pour moi aussi! Je vous remercie. Cela aurait dû être la réponse officielle
Fandango68

1
@RiZKiT, onene le coupera pas comme "Le gestionnaire est exécuté une fois par élément par type d'événement . Il désactivera automatiquement l'événement qui l'a déclenché, mais l'autre persistera toujours et offprendra soin des deux de toute façon. Voir mon question: fonction qui se déclenchera exactement une fois pour un nombre quelconque d'événements
KyleMit

13

Cela ferait le travail et éviterait le problème que vous ne pouvez plus sélectionner une partie du texte avec la souris.

$("input[type=text]").click(function() {
    if(!$(this).hasClass("selected")) {
        $(this).select();
        $(this).addClass("selected");
    }
});
$("input[type=text]").blur(function() {
    if($(this).hasClass("selected")) {
        $(this).removeClass("selected");
    }
});

1
Important de conserver la possibilité de sélectionner une partie du texte avec la souris. J'utilise ceci et son A1
Philibert Perusse

2
Trop de choses se passent ici, utilisez la solution focus / mouseup de user2072367
George

@George user2072367 est assez bon, mais il a de sérieux défauts. Découvrez ma solution (:
animatedgif

6

Cette version fonctionne sur iOS et corrige également le glisser-sélectionner standard sur Windows Chrome

var srcEvent = null;

$("input[type=text],input[type=number]")

    .mousedown(function (event) {
        srcEvent = event;
    })

    .mouseup(function (event) {
        var delta = Math.abs(event.clientX - srcEvent.clientX) 
                  + Math.abs(event.clientY - srcEvent.clientY);

        var threshold = 2;
        if (delta <= threshold) {
                   try {
                        // ios likes this but windows-chrome does not on number fields
                        $(this)[0].selectionStart = 0;
                        $(this)[0].selectionEnd = 1000;
                    } catch (e) {
                        // windows-chrome likes this
                        $(this).select();
                    }
        }
    });

http://jsfiddle.net/Zx2sc/2/


Modifié pour ajouter de vilains essais / captures pour apaiser les navigateurs
anihilnine

5

Le problème avec la plupart de ces solutions est qu'elles ne fonctionnent pas correctement lors du changement de position du curseur dans le champ de saisie.

L' onmouseupévénement modifie la position du curseur dans le champ, qui est déclenché après onfocus(au moins dans Chrome et FF). Si vous supprimez inconditionnellement le, mouseupl'utilisateur ne peut pas modifier la position du curseur avec la souris.

function selectOnFocus(input) {
    input.each(function (index, elem) {
        var jelem = $(elem);
        var ignoreNextMouseUp = false;

        jelem.mousedown(function () {
            if (document.activeElement !== elem) {
                ignoreNextMouseUp = true;
            }
        });
        jelem.mouseup(function (ev) {
            if (ignoreNextMouseUp) {
                ev.preventDefault();
                ignoreNextMouseUp = false;
            }
        });
        jelem.focus(function () {
            jelem.select();
        });
    });
}
selectOnFocus($("#myInputElement"));

Le code empêchera conditionnellement le mouseupcomportement par défaut si le champ n'a pas actuellement le focus. Cela fonctionne pour ces cas:

  • cliquer lorsque le champ n'est pas focalisé
  • en cliquant lorsque le champ a le focus
  • tabulation dans le champ

J'ai testé cela dans Chrome 31, FF 26 et IE 11.


Cela fonctionne parfaitement pour les événements de clic, mais si j'utilise tab pour passer au champ de saisie suivant, je vois que le contenu est sélectionné et désélectionné juste plus tard
ToX 82

4

Trouvé une solution géniale en lisant ce fil

$(function(){

    jQuery.selectText('input:text');
    jQuery.selectText('input:password');

});

jQuery.extend( {
    selectText: function(s) { 
        $(s).live('focus',function() {
            var self = $(this);
            setTimeout(function() {self.select();}, 0);
        });
    }
});

... qui est essentiellement la même réponse que Piskvor .
Oliver

n'oubliez pas tous les autres types de texte HTML5, par exemple 'input [type = email]'
jamiebarrow

3

Je viens de fin 2016 et ce code ne fonctionne que dans les versions récentes de jquery (jquery-2.1.3.js dans ce cas).

if ($(element).is("input")) {
    $(element).focus(function () {
        $(element).select();
    });
}

2

Si j'utilise FF 16.0.2 et jquery 1.8.3, tout le code de la réponse n'a pas fonctionné.
J'utilise du code comme celui-ci et je travaille.

$("input[type=text]").focus().select();

4
Cela ne répond pas à la question, qui est de savoir comment sélectionner le contenu d'une zone de saisie lorsque l'utilisateur concentre le champ . Cela se concentrera immédiatement et sélectionnera le code, sans intervention de l'utilisateur.
saluce

@saluce je ne comprends pas ce que tu veux dire? ce que le questionneur veut, c'est quand il sélectionne le champ, tout le texte actuel est sélectionné. Et mon code devrait le faire. Je l'utilise même pour mon projet, comme le moment où j'écris cette réponse.
GusDeCooL

1
Ce code se concentrera et sélectionnera tout lors de son exécution, mais le code, en soi, n'est pas lié à un événement généré par l' utilisateur , tel que cliquer sur la zone de texte. Par exemple, $("input[type=text]").on('click', function () { $(this).focus.select(); })provoque le focus et la sélection lorsque l'utilisateur clique sur la zone, car il est exécuté lorsque l'utilisateur clique sur la zone. Sans le gestionnaire d'événements, le code ne répond pas à la question, d'où le downvote et le commentaire. Fondamentalement, vous avez obtenu la partie "tout le texte actuel est sélectionné" mais pas la partie "lorsqu'il sélectionne le champ".
saluce

1
@GusDeCooL assez drôle (même si ce n'est pas exactement ce qu'il a demandé), je voulais le même résultat que vous sur ce point :)
Robbie Averill

2
var timeOutSelect;
$("input[type=text]").focus(function() { 
        var save_this = $(this);
        clearTimeout(timeOutSelect);
        timeOutSelect = window.setTimeout (function(){ 
                save_this.select(); 
        }, 100);
});

Utilisez clearTimeout pour plus de sécurité si vous basculez rapidement entre deux entrées. ClearTimeout nettoie l'ancien timeout ...


Veuillez modifier avec plus d'informations. Les réponses de code uniquement et "essayez ceci" sont déconseillées, car elles ne contiennent aucun contenu consultable et n'expliquent pas pourquoi quelqu'un devrait "essayer ceci". Nous nous efforçons ici d'être une ressource de connaissances.
Brian Tompsett - 汤 莱恩

2

Fonctionne très bien avec le JavaScript natif select().

$("input[type=text]").focus(function(event) {
   event.currentTarget.select();
});

ou en général:

$("input[type=text]")[0].select()

1

Ou vous pouvez simplement utiliser <input onclick="select()">Works perfect.


non ça ne marche pas. cela fonctionne pour sélectionner l'ensemble. mais essayez de sélectionner une partie du texte manuellement, vous ne pourrez pas le faire.
Sujay Phadke


0
<script>$.ready( $("input[type=text]").attr("onclick" , "this.select()"));<script>

Cela sera probablement marqué comme une réponse de faible qualité car il n'a aucune explication de ce qui se passe.
tumultous_rooster

Votre $.readyn'est pas correct. Vous devez lui passer une fonction pour la retarder attrjusqu'à ce que le document soit prêt. Vous le faites immédiatement, puis passez la collection d'éléments à $.ready.
doug65536

Évitez également le «onclick», en particulier de cette façon. Utilisez addEventListener.
doug65536

0

J'utilise toujours requestAnimationFrame()pour sauter par-dessus les mécanismes internes post-événement et cela fonctionne parfaitement dans Firefox. N'ont pas été testés dans Chrome.

$("input[type=text]").on('focus', function() {
    requestAnimationFrame(() => $(this).select());
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.