Выбор текста в фокусе с помощью jQuery, не работающего в Safari и Chrome

85

У меня есть следующий код jQuery (похожий на этот вопрос ), который работает в Firefox и IE, но не работает (без ошибок, просто не работает) в Chrome и Safari. Есть идеи обходного пути?

$("#souper_fancy").focus(function() { $(this).select() });
user140550
источник
Я хочу точного поведения в сафари iPad / iPhone. Это не работает в браузерах iPod / iPhone. любая подсказка. Ниже принятый ответ предназначен только для настольных компьютеров Chrome / safari.
Anand
5
Примечание: принятый здесь ответ решает только половину проблемы. Это заставляет выбор работать, но затрудняет отмену выбора при последующих щелчках. Лучшее решение можно найти здесь: stackoverflow.com/questions/3380458/…
SDC

Ответы:

188

Это событие onmouseup приводит к тому, что выбор становится невыделенным, поэтому вам просто нужно добавить:

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

источник
3
Подробнее об ошибке здесь: code.google.com/p/chromium/issues/detail?id=4505
Раджат
Как добиться того же с помощью Prototype?
tehfink
Вы также можете попробовать выполнить привязку к событию click и избежать необходимости делать две привязки.
uglymunky
@uglymunky В зависимости от того, что вы делаете, привязка к событию щелчка не будет работать во всех случаях - в конце концов, есть другие средства выбора поля ввода, кроме щелчка по нему, и вы хотите, чтобы они тоже работали (например, вкладка в это)
Tacroy
2
Я хочу точного поведения в сафари iPad / iPhone. Это не работает в браузерах iPod / iPhone. любая подсказка.
Anand
25
$('#randomfield').focus(function(event) {
    setTimeout(function() {$('#randomfield').select();}, 0);
});
Alex0007
источник
3
Это лучший ответ, если вы пытаетесь выделить текст в поле формы для приложения PhoneGap, работающего на Android. Это дает пользователю визуальную индикацию того, что текст выделен, тогда как принятый ответ - нет.
BallisticPugh
4

Это отлично работает для элементов input type = "text". Что это за элемент #souper_fancy?

$("#souper_fancy").focus(function() {
    $(this).select();
});
Джо Чанг
источник
это элемент type = "text". Я тоже попробовал $ ("input [type = text]"). По-прежнему не работает с jQuery 1.3.2 в Safari.
user140550
3

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

Чтобы избежать этого и снова заставить выделение текста работать, вы можете установить флаг на FOCUS, прочитать его из MOUSEUP и сбросить его, чтобы будущие события MOUSEUP работали должным образом.

$("#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
источник
1

Хотя это работает для выбора его в IE, Firefox, Chrome, Safari и Opera, оно не позволит вам редактировать его, щелкнув второй раз в Firefox, Chrome и Safari. Не совсем уверен, но я думаю, что это может быть связано с тем, что эти 3 браузера повторно выдают событие фокуса, даже если поле уже имеет фокус, что никогда не позволяет вам фактически вставить курсор (поскольку вы выбираете его снова), тогда как в IE и Opera, похоже, этого не происходит, поэтому событие фокуса не запускалось снова, и, таким образом, курсор вставляется.

Я нашел лучшее исправление в этом сообщении стека, которое не имеет этой проблемы и работает во всех браузерах.

предприниматель
источник
1

Это должно работать и в хроме:

$("#souper_fancy").focus(function() {
    var tempSouper = $(this);
    setTimeout(function(){
        tempSouper.select();
    },100);
});
Rubiwachs
источник
Пожалуйста, подумайте о добавлении конструктивного отзыва о том, почему OP видит проблему и ваше решение ее устраняет.
Мирко Адари
1

Поскольку при использовании setTimeout появляется мерцание, существует другое решение на основе событий. Таким образом, событие 'focus' присоединяет событие 'mouseup', и обработчик событий снова отключается.

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

Затем подключите первое событие

    $('.varquantity').on('focus', selectAllOnFocus);
user2941872
источник
1

Используйте setSelectionRange()внутри обратного вызова, чтобы 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;
    });
});

Использовать setSelectionRange()вместо, select()поскольку select()не работает в мобильном Safari (см. Программный выбор текста в поле ввода на устройствах iOS (мобильный Safari) ).

requestAnimationFrameПеред выделением текста необходимо подождать using , иначе элемент не будет правильно прокручен в поле зрения после появления клавиатуры на iOS.

При использовании setSelectionRange()важно установить тип ввода text, иначе в Chrome могут возникнуть исключения (см. SelectionStart / selectionEnd о input type = "number", больше не разрешенном в Chrome ).

Эндрю
источник
0

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

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

(без setTimeout () он не работает в Safari, мобильном Safari и MS Edge)

Клаудио
источник