À la recherche d'une meilleure solution pour contourner le bogue de Chrome select on focus

j'ai le même problème que l'utilisateur dans cette question , qui est due à ce bug dans Webkit. Cependant, la solution de contournement fournie ne fonctionne pas pour mon application. Permettez-moi de reformuler le problème afin que vous n'ayez pas à lire une autre question:

j'essaie de sélectionner tout le texte d'une textarea quand il se focalise. La suite de jQuery code fonctionne dans IE/FF/Opera:

$('#out').focus(function(){
  $('#out').select();
});

Cependant, en Chrome / Safari le texte est sélectionné -- très brièvement--mais l'événement mouseUp est déclenché et le texte est désélectionné. La solution de contournement suivante est proposée dans les liens ci-dessus:

$('#out').mouseup(function(e){
  e.preventDefault();
});

Toutefois, cette solution de contournement n'est pas bon pour moi . Je veux sélectionner tout le texte seulement lorsque l'utilisateur donne le focus textarea. Il doit puis ne peut sélectionner qu'une partie du texte s'il le souhaite. Comment peut-on penser de une solution qui répond toujours à cette exigence?

33
demandé sur Community 2010-08-01 06:02:11

8 réponses

et ça?

$('#out').focus(function () {
    $('#out').select().mouseup(function (e) {
        e.preventDefault();
        $(this).unbind("mouseup");
    });
});
29
répondu tcooc 2010-08-01 02:24:39

la réponse acceptée (et en gros toutes les autres solutions que j'ai trouvées jusqu'à présent) ne fonctionne pas avec le clavier focus, I. E. presser la languette, du moins pas dans mon Chrome 21. J'utilise l'extrait suivant à la place:

$('#out').focus(function () {
  $(this).select().one('mouseup', function (e) {
    $(this).off('keyup');
    e.preventDefault();
  }).one('keyup', function () {
    $(this).select().off('mouseup');
  });
});

e.preventDefault() dans le handler keyup ou focus n'aide pas, de sorte que le désélectionnement après un focus clavier ne semble pas se produire dans leurs handlers par défaut, mais plutôt quelque part entre les événements focus et keyup .

comme suggéré par @BarelyFitz, il serait peut-être préférable de travailler avec des événements nommés afin de ne pas décrocher accidentellement d'autres gestionnaires d'événements. Remplacer 'keyup' par 'keyup.selectText' et 'mouseup' par 'mouseup.selectText' .

24
répondu Adrian Heine 2014-07-10 19:16:10

pourquoi pas simplement:

$('#out').focus(function(){
    $(this).one('mouseup', function() {
        $(this).select();
    });
});

Semble fonctionner dans tous les principaux navigateurs...

3
répondu Barbarab 2013-04-19 12:20:47

faire un bool . Réglez-le sur true après un événement focus et réinitialisez-le après un événement souris. Pendant la souris vers le haut, si c'est true , vous savez que l'utilisateur vient de sélectionner le champ de texte; donc vous savez que vous devez empêcher la souris vers le haut de se produire. Sinon, vous devez le laisser passer.

var textFieldGotFocus = false;

$('#out').focus(function()
{
    $('#out').select();
    textFieldGotFocus = true;
});

$('#out').mouseup(function(e)
{
    if (textFieldGotFocus)
        e.preventDefault();
});

$(document).mouseup(function() { textFieldGotFocus = false; });

il est important que vous mettiez l'auditeur mouseup qui réinitialise la variable sur document , car il n'est pas garanti que l'utilisateur bouton de la souris sur le champ de texte.

2
répondu zneak 2010-08-01 02:12:23

sélectionnez le texte avant de mettre l'accent sur la boîte de saisie.

$('#out').select().focus();
2
répondu finpup 2014-01-15 21:42:59

une approche très légèrement différente consisterait à séparer l'événement de mise au point de la séquence de la souris. Cela fonctionne très bien pour moi - pas de variables d'état, pas de gestionnaires qui fuient, pas de retrait par inadvertance des gestionnaires, et cela fonctionne avec le clic, l'onglet, ou la mise au point programmatique. Code et jsFiddle ci - dessous -

$('#out').focus(function() {
    $(this).select();
});
$('#out').on('mousedown.selectOnFocus', function() {
    if (!($(this).is(':focus'))) {
        $(this).focus();
        $(this).one('mouseup.selectOnFocus', function(up) {
            up.preventDefault();
        });
    }
});

https://jsfiddle.net/tpankake/eob9eb26/27 /

2
répondu tpankake 2015-06-23 02:33:34
onclick="var self = this;setTimeout(function() {self.select();}, 0);"
1
répondu Terje 2012-11-24 15:39:39

la solution de digitalfresh est la plupart du temps là, mais a un bug là si vous déclenchez manuellement .focus() en utilisant JS (donc pas en utilisant un clic), ou si vous tabulez sur le champ, alors vous obtenez un événement mouseup non désiré lié - cela provoque le premier clic qui devrait désélectionner le texte pour être ignoré.

à résoudre:

var out = $('#out');
var mouseCurrentlyDown = false;

out.focus(function () {
  out.select();

  if (mouseCurrentlyDown) {
    out.one('mouseup', function (e) {
      e.preventDefault();
    });  
  }
}).mousedown(function() {
  mouseCurrentlyDown = true;
});

$('body').mouseup(function() {
  mouseCurrentlyDown = false;
});

Remarque: L'événement mouseup devrait être sur le corps et pas l'entrée que nous voulons compte pour l'utilisateur mousedown-ing dans l'entrée, déplacement de la souris hors de l'entrée,puis mouseup-ing.

0
répondu Jai 2013-01-01 23:28:43