La sélection de texte sur le focus à l'aide de jQuery ne fonctionne pas dans Safari et Chrome

85

J'ai le code jQuery suivant (similaire à cette question ) qui fonctionne dans Firefox et IE, mais échoue (pas d'erreurs, ne fonctionne tout simplement pas) dans Chrome et Safari. Des idées pour une solution de contournement?

$("#souper_fancy").focus(function() { $(this).select() });
user140550
la source
Je veux un comportement exact en safari sur iPad / iPhone. Cela ne fonctionne pas dans les navigateurs iPod / iPhone. tout indice. La réponse acceptée ci-dessous concerne uniquement Chrome / Safari sur ordinateur de bureau.
Anand
5
Remarque: la réponse acceptée ici ne résout que la moitié du problème. Cela rend le travail de sélection, mais il est difficile de le désélectionner ensuite avec les clics suivants. Une meilleure solution peut être trouvée ici: stackoverflow.com/questions/3380458/…
SDC

Réponses:

188

C'est l'événement onmouseup qui provoque la désélection de la sélection, il vous suffit donc d'ajouter:

$("#souper_fancy").mouseup(function(e){
    e.preventDefault();
});

la source
3
Plus de référence sur le bogue ici: code.google.com/p/chromium/issues/detail?id=4505
Rajat
Comment réaliser la même chose avec Prototype?
tehfink
Vous pouvez également essayer de lier à l'événement «click» et éviter d'avoir à faire deux liaisons.
uglymunky
@uglymunky Selon ce que vous faites, la liaison à l'événement de clic ne fonctionnera pas dans tous les cas - après tout, il existe d'autres moyens de sélectionner un champ de saisie que de cliquer dessus, et vous voulez que ceux-ci fonctionnent également (par exemple, tabbing in to it)
Tacroy
2
Je veux un comportement exact en safari sur iPad / iPhone. Cela ne fonctionne pas dans les navigateurs iPod / iPhone. tout indice.
Anand
25
$('#randomfield').focus(function(event) {
    setTimeout(function() {$('#randomfield').select();}, 0);
});
Alex0007
la source
3
C'est la meilleure réponse si vous essayez de sélectionner du texte dans un champ de formulaire pour une application PhoneGap exécutée sur Android. Cela donne une indication visuelle à l'utilisateur que le texte est sélectionné, contrairement à la réponse acceptée.
BallisticPugh
4

Cela fonctionne très bien pour les éléments input type = "text". Quel type d'élément est #souper_fancy?

$("#souper_fancy").focus(function() {
    $(this).select();
});
Joe Chung
la source
c'est un élément type = "text". J'ai également essayé $ ("input [type = text]"). Ne fonctionne toujours pas avec jQuery 1.3.2 dans Safari.
user140550
3

Le simple fait d'empêcher la valeur par défaut sur la souris entraîne l'activation permanente de la sélection de texte. L'événement MOUSEUP est chargé d'effacer la sélection de texte. Cependant, en empêchant son comportement par défaut, vous ne pouvez pas désélectionner le texte à l'aide de la souris.

Pour éviter cela et que la sélection de texte fonctionne à nouveau, vous pouvez définir un indicateur sur FOCUS, le lire à partir de MOUSEUP et le réinitialiser afin que les futurs événements MOUSEUP fonctionnent comme prévu.

$("#souper_fancy").focus(function() {
    $(this).select();

    //set flag for preventing MOUSEUP event....
    $this.data("preventMouseUp", true);
});

$("#souper_fancy").mouseup(function(e) {
    var preventEvent = $this.data("preventMouseUp");

    //only prevent default if the flag is TRUE
    if (preventEvent) {
        e.preventDefault();
    }

    //reset flag so MOUSEUP event deselect the text
    $this.data("preventMouseUp", false);
});
ThiagoPXP
la source
1

Bien que cela fonctionne pour le sélectionner dans IE, Firefox, Chrome, Safari et Opera, il ne vous permettra pas de le modifier en cliquant une deuxième fois dans Firefox, Chrome et Safari. Pas tout à fait sûr, mais je pense que cela peut être dû au fait que ces 3 navigateurs réémettent un événement de focus même si le champ a déjà le focus, ne vous permettant donc jamais d'insérer le curseur (puisque vous le sélectionnez à nouveau), alors que dans IE et Opera, il semble que ce ne soit pas le cas, donc l'événement de focus n'a pas été déclenché à nouveau et ainsi le curseur est inséré.

J'ai trouvé une meilleure solution dans cet article de Stack qui n'a pas ce problème et fonctionne dans tous les navigateurs.

johntrepreneur
la source
1

Cela devrait également fonctionner dans Chrome:

$("#souper_fancy").focus(function() {
    var tempSouper = $(this);
    setTimeout(function(){
        tempSouper.select();
    },100);
});
rubiwachs
la source
Veuillez envisager d'ajouter des commentaires constructifs sur les raisons pour lesquelles OP voit le problème et votre solution le résout.
Mirko Adari
1

Comme il y a un scintillement lorsque vous utilisez setTimeout, il existe une autre solution basée sur les événements. De cette façon, l'événement 'focus' attache l'événement 'mouseup' et le gestionnaire d'événements se détache à nouveau.

    function selectAllOnFocus(e) {
    if (e.type == "mouseup") { // Prevent default and detach the handler
        console.debug("Mouse is up. Preventing default.");
        e.preventDefault();
        $(e.target).off('mouseup', selectAllOnFocus);
        return;
    }
    $(e.target).select();
    console.debug("Selecting all text");
    $(e.target).on('mouseup', selectAllOnFocus);
}

Puis câblez le premier événement

    $('.varquantity').on('focus', selectAllOnFocus);
user2941872
la source
1

Utilisez à l' setSelectionRange()intérieur d'un rappel pour requestAnimationFrame():

$(document).on('focus', '._selectTextOnFocus', (e) => {
    var input = e.currentTarget;
    var initialType = e.currentTarget.type;

    requestAnimationFrame(() => {
        // input.select() is not supported on iOS
        // If setSelectionRange is use on a number input in Chrome it throws an exception,
        // so here we switch to type text first.
        input.type = "text";
        input.setSelectionRange(0, Number.MAX_SAFE_INTEGER || 9999);
        input.type = initialType;
    });
});

Utiliser à la setSelectionRange()place de select()puisque select()ne fonctionne pas dans Safari mobile (voir Sélection par programme de texte dans un champ de saisie sur les appareils iOS (Safari mobile) ).

Il est nécessaire d'attendre requestAnimationFrameavant de sélectionner le texte, sinon l'élément ne défilera pas correctement après que le clavier soit monté sur iOS.

Lors de l'utilisation, setSelectionRange()il est important de définir le type d'entrée sur text, sinon il peut générer des exceptions sur Chrome (voir selectionStart / selectionEnd sur input type = "number" n'est plus autorisé dans Chrome ).

Andrewh
la source
0

Si quelqu'un rencontre à nouveau ce problème, j'ai ici une solution JS pure qui fonctionne (pour le moment) sur tous les navigateurs, y compris. mobile

<input type="text" value="Hello world..." onFocus="window.setTimeout(() => this.select());">

(sans setTimeout (), cela ne fonctionne pas sur Safari, Safari mobile et MS Edge)

Claudio
la source