Поиск лучшего обходного пути для Chrome для выбора фокуса

У меня такая же проблема, как у пользователя в этот вопрос, который обусловлен эта ошибка в Webkit. Однако обходной путь не будет работать для моего приложения. Позвольте мне переформулировать проблему, чтобы вам не пришлось читать другой вопрос:

Я пытаюсь выбрать весь текст в текстовом поле, когда он получает фокус. Следующий код jQuery работает в IE/FF/Opera:

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

Однако в Chrome/Safari текст выбран - очень кратко - но тогда событие mouseUp запускается и текст отменяется. В приведенных выше ссылках предлагается следующее обходное решение:

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

Однако это обходное решение для меня не подходит. Я хочу выделить весь текст только тогда, когда пользователь дает фокус текстовой области. Затем он должен иметь возможность выбирать только часть текста, если он выберет. Может ли кто-нибудь подумать об обходном пути, который все еще соответствует этому требованию?

Ответ 1

Как насчет этого?

$('#out').focus(function () {
    $('#out').select().mouseup(function (e) {
        e.preventDefault();
        $(this).unbind("mouseup");
    });
});

Ответ 2

Принятый ответ (и в основном любое другое решение, которое я нашел до сих пор) не работает с фокусом клавиатуры, т.е. е. нажатие вкладки, по крайней мере, не в моем Chromium 21. Вместо этого я использую следующий фрагмент:

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

e.preventDefault() в обработчике keyup или focus не помогает, поэтому невыделение после фокуса клавиатуры, похоже, не происходит в обработчиках по умолчанию, а скорее где-то между событиями focus и keyup.

Как было предложено @BarelyFitz, было бы лучше работать с событиями с именами, чтобы случайно не развязать другие обработчики событий. Замените 'keyup' на 'keyup.selectText' и 'mouseup' на 'mouseup.selectText' для этого.

Ответ 3

Почему бы просто:

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

Кажется, работает во всех основных браузерах...

Ответ 4

Сделайте bool. Установите значение true после события фокусировки и reset после события mouse up. Во время мышки вверх, если он true, вы знаете, что пользователь только что выбрал текстовое поле; поэтому вы знаете, что вы должны предотвратить появление мыши. В противном случае вы должны позволить ему пройти.

var textFieldGotFocus = false;

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

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

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

Важно, чтобы вы поместили прослушиватель мыши, который сбрасывает переменную на document, так как он не гарантирует, что пользователь отпустит кнопку мыши над текстовым полем.

Ответ 5

Выберите текст, прежде чем поместить фокус в поле ввода.

$('#out').select().focus();

Ответ 6

Совсем немного другой подход заключается в том, чтобы отделить фокусное событие от последовательности мыши. Это действительно хорошо для меня - никаких переменных состояния, никаких пропущенных обработчиков, не случайного удаления обработчиков и работает с щелчком, вкладкой или программным фокусом. Код и jsFiddle ниже -

$('#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/

Ответ 7

onclick="var self = this;setTimeout(function() {self.select();}, 0);"

Ответ 8

Решение digitalfresh в основном есть, но имеет ошибку в том, что если вы вручную запускаете .focus() с помощью JS (так что не используя клик), или если вы вставляете в поле, то вы получаете нежелательное событие привязки мыши - это вызывает первый щелчок, который должен отменить выделение текста.

Чтобы решить:

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

Примечание. Событие mouseup должно быть на корпусе, а не на входе, так как мы хотим учесть пользователя, находящееся на входе, перемещая мышь из ввода, а затем мышь.