Sélectionner le texte sur focus en utilisant jQuery ne fonctionne pas dans Safari et Chrome

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. Toutes les idées pour une solution de contournement?

$("#souper_fancy").focus(function() { $(this).select() });
83
demandé sur Community 2009-08-13 06:24:52

9 réponses

c'est l'événement onmouseup qui fait que la sélection n'est pas sélectionnée, donc vous avez juste besoin d'ajouter:

$("#souper_fancy").mouseup(function(e){
    e.preventDefault();
});
184
répondu 2009-08-13 02:46:32
$('#randomfield').focus(function(event) {
    setTimeout(function() {$('#randomfield').select();}, 0);
});
24
répondu Alex0007 2012-07-14 02:18:55

cela fonctionne très bien pour le type d'entrée=éléments" text". Quel genre d'élément est #souper_fancy?

$("#souper_fancy").focus(function() {
    $(this).select();
});
4
répondu Joe Chung 2009-08-13 02:33:12

le simple fait de prévenir le défaut sur mouseup fait que la sélection de texte est activée à tout moment. L'événement MOUSEUP est responsable d'effacer la sélection de texte. Cependant, en empêchant son comportement par défaut, vous êtes incapable de désélectionner le texte en utilisant la souris.

pour éviter cela et obtenir la sélection de texte de travailler à nouveau, vous pouvez mettre un drapeau sur le FOCUS, le lire à partir de MOUSEUP et de le réinitialiser de sorte que les événements futurs de MOUSEUP fonctionneront 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);
});
2
répondu ThiagoPXP 2014-10-16 18:59:08

bien que cela fonctionne pour le sélectionner dans IE, Firefox, Chrome, Safari, et Opera, il ne vous permettra pas de l'éditer en cliquant une deuxième fois dans Firefox, Chrome, et Safari. Pas tout à fait sûr, mais je pense que cela peut être dû à ces 3 navigateurs re-émission d'un événement de mise au point même si le champ a déjà la mise au point donc ne vous permettant jamais d'insérer le curseur réellement (puisque vous le sélectionnez à nouveau), alors que dans IE et Opera il semble qu'il ne fait pas cela de sorte que l'événement de mise au point n'a pas été tiré à nouveau et ainsi, le curseur est insérée.

j'ai trouvé une meilleure solution dans cette pile de post qui n'a pas ce problème et fonctionne dans tous les navigateurs.

1
répondu johntrepreneur 2017-05-23 11:46:34

cela devrait fonctionner aussi en chrome:

$("#souper_fancy").focus(function() {
    var tempSouper = $(this);
    setTimeout(function(){
        tempSouper.select();
    },100);
});
1
répondu rubiwachs 2013-01-24 12:12:48

parce qu'il y a des clignotements lorsque vous utilisez setTimeout, il y a 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 de l'événement 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 filez le premier événement

    $('.varquantity').on('focus', selectAllOnFocus);
1
répondu user2941872 2015-07-11 19:03:44

Utiliser setSelectionRange() à l'intérieur d'un rappel à 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 setSelectionRange() au lieu de select() car select() ne fonctionne pas dans le Safari mobile (Voir sélection programmatique de texte dans un champ d'entrée sur les appareils iOS (Safari mobile) ).

il est nécessaire d'attendre avec requestAnimationFrame avant de sélectionner le texte, sinon l'élément n'est pas correctement affiché après le clavier arrive sur iOS.

Lorsqu'on utilise setSelectionRange() , il est important de régler le type d'entrée à text , sinon il peut y avoir des exceptions sur Chrome (voir selectionStart/selectionEnd sur le type d'entrée=" Nombre "n'est plus autorisé dans Chrome ).

0
répondu andrewh 2017-12-05 04:15:07

si quelqu'un vient à nouveau à travers ce problème, j'ai obtenu ici une solution pure JS qui est (en ce moment) de travail sur tous les navigateurs incl. mobile

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

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

0
répondu Claudio 2018-06-20 14:47:57