JQuery ввода выбрать все в фокусе

327

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

$("input[type=text]").focus(function() {
   $(this).select();
});

Я хочу, чтобы все оставалось выбранным.

Тим
источник
Какой браузер, кажется, работает нормально для меня в FF?
R0MANARMY
8
Chrome = провал для этого
wowo_999
1
Я использовал Chrome, но .click () решает проблему :)
Тим
4
Примечание: принятый ответ здесь решает только половину проблемы. Это заставляет работать выбор, но затрудняет его отмену последующими щелчками. Лучшее решение можно найти здесь: stackoverflow.com/questions/3380458/…
SDC

Ответы:

481

Попробуйте использовать clickвместо focus. Кажется, он работает как для мыши, так и для ключевых событий (по крайней мере, в Chrome / Mac):

jQuery <версия 1.7:

$("input[type='text']").click(function () {
   $(this).select();
});

JQuery версия 1.7+:

$("input[type='text']").on("click", function () {
   $(this).select();
});

Вот демо

karim79
источник
62
проблема в том, что вы больше не можете выделять часть текста с помощью мыши, как только происходит щелчок, выделяется полный текст.
Хелин Ван
6
Не жизнеспособное решение для меня. Это создает проблему, описанную Ван.
Маркес
1
Ниже представлено решение Nianpeng, которое также работает с выделением текста мышью.
Филибер Perusse
4
@AwQiruiGuo $ .fn.on ('click', ..) может использовать меньше памяти и работать с динамически добавляемыми дочерними элементами.
Рикки Бойс
7
Это не работает для фокусировки поля во вкладках.
Колин Брим
65

Я думаю, что происходит так:

focus()
   UI tasks related to pre-focus
   callbacks
       select()
   UI tasks related to focus (which unselect again)

Обходной путь может вызывать select () асинхронно, чтобы он полностью выполнялся после focus ():

$("input[type=text]").focus(function() { 
    var save_this = $(this);
    window.setTimeout (function(){ 
       save_this.select(); 
    },100);
});
Писквор покинул здание
источник
3
$ ("input [type = text]"). focus (function () {var save_this = $ (this); window.setTimeout (function () {save_this.select ();}, 100);});
Этьен
@etienne: О, хороший момент: thisв таких сферах обработка данных немного неожиданна. Я обновлю код.
Писквор покинул здание
3
значение тайм-аута 0 тоже нормально, и функция «focusin ()» также работает с этим методом.
Танги
4
да, вам даже не нужно устанавливать период. 0 будет в порядке, поскольку тайм-ауты выполняются в конце текущего стека вызовов. это означает, что все события фокуса и щелчка срабатывают, и затем ваша функция запускается
Джошуа Бамбрик
1
Тайм-аут 0, кажется, имеет проблему, что событие «click» может сработать в более позднем кадре, отменив выбор поля снова. Я считаю, что тайм-аут 10, кажется, работает довольно хорошо - без заметной задержки, но более надежно, чем 0.
Philh
57

Я думаю, что это лучшее решение. В отличие от простого выбора в событии onclick, это не мешает выделению / редактированию текста с помощью мыши. Он работает с основными движками рендеринга, включая IE8.

$('input').on('focus', function (e) {
    $(this)
        .one('mouseup', function () {
            $(this).select();
            return false;
        })
        .select();
});

http://jsfiddle.net/25Mab/9/

user2072367
источник
4
Это работает только для существующих полей, вот обновление для привязки его к новым полям ввода: jsfiddle.net
adriaan
Иногда фокус может быть дан без щелчка, и это хорошо с этим справляется. Из-за этого, для меня это самый чистый ответ - даже при том, что при каждом
фокусе
Это не позволяет второй щелчок внутри числовых входов, чтобы выделить другую часть текста с помощью мыши. Удаление второго, select()похоже, работает.
dperish
Еще лучше с дополнительным$('input[autofocus]').select();
Даниэль Блейштайнер
38

Здесь есть несколько достойных ответов, и @ user2072367 - мой любимый, но он дает неожиданный результат, когда вы фокусируетесь не на клике, а на вкладке. (неожиданный результат: чтобы выделить текст после фокуса через вкладку, необходимо щелкнуть еще один раз)

Эта скрипка исправляет эту небольшую ошибку и дополнительно хранит $ (this) в переменной, чтобы избежать избыточного выбора DOM. Проверьте это! (:

Протестировано в IE> 8

$('input').on('focus', function() {
    var $this = $(this)
        .one('mouseup.mouseupSelect', function() {
            $this.select();
            return false;
        })
        .one('mousedown', function() {
            // compensate for untriggered 'mouseup' caused by focus via tab
            $this.off('mouseup.mouseupSelect');
        })
        .select();
});
animatedgif
источник
2
+1 Ваши и @ user2072367 решения являются самыми чистыми во всей этой цепочке, и я бы хотел, чтобы был способ быстрее подняться на вершину.
KyleMit
1
Даже работает, если пользователь пытается выделить весь текст самостоятельно, браво.
Витани
Для меня это не работает на ie11 на Windows 8.1. Это работает в ie11 на Windows 7 и Windows 10
Ларс Томас Бредланд
1
@LarsThomasBredland Я только что попробовал на win 8.1 + ie11, и он работает, как ожидалось. Что для вас "не работает"?
animatedgif
Он просто ничего не выбирает. (Я тестировал на другом win8, и он там работает - тот же уровень ОС и версия)
Ларс Томас Бредланд
21

После тщательного анализа я предлагаю это как более чистое решение в этой теме:

$("input").focus(function(){
    $(this).on("click.a keyup.a", function(e){      
        $(this).off("click.a keyup.a").select();
    });
});

Демо в jsFiddle

Эта проблема:

Вот немного объяснения:

Во-первых, давайте посмотрим на порядок событий, когда вы щелкаете мышью или вкладываете в поле.
Мы можем регистрировать все соответствующие события, как это:

$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
              function(e) { console.log(e.type); });

фокус событий

Примечание : я изменил это решение, чтобы использовать его, clickа не так, mouseupкак это происходит позже в конвейере событий, и, похоже, вызывает некоторые проблемы в Firefox согласно комментарию @ Jocie.

Некоторые браузеры пытаются позиционировать курсор во время событий mouseupили click. Это имеет смысл, поскольку вы можете запустить каретку в одной позиции и перетащить ее, чтобы выделить текст. Он не может обозначать положение каретки, пока вы на самом деле не подняли мышь. Таким образом, функции, которые обрабатывают focus, обречены реагировать слишком рано, оставляя браузер переопределять ваше позиционирование.

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

Решение:

Вместо этого, в focusобработчике событий мы можем быстро подключить прослушиватели для событий click(click in) и keyup(tab in), которые будут запущены.

Примечание : Keyup события табуляции будет фактически запускаться в новом поле ввода, а не в предыдущем

Мы хотим запустить событие только один раз. Мы могли бы использовать .one("click keyup), но это вызвало бы обработчик события один раз для каждого типа события . Вместо этого, как только будет нажата мышь или клавиша, мы вызовем нашу функцию. Первое, что мы сделаем, это удалим обработчики для обоих. Таким образом, не имеет значения, будем ли мы вкладывать или вкладывать. Функция должна выполняться ровно один раз.

Примечание . Большинство браузеров естественным образом выделяют весь текст во время события табуляции, но, как указывает animatedgif , мы по-прежнему хотим обрабатывать keyupсобытие, в противном mouseupслучае событие все равно будет задерживаться в любое время, когда мы добавили вкладку. Мы слушаем оба, чтобы мы могли включить от слушателей, как только мы обработали выбор.

Теперь мы можем позвонить select()после того, как браузер сделал свой выбор, поэтому мы обязательно переопределим поведение по умолчанию.

Наконец, для дополнительной защиты, мы можем добавить пространство имен событий к mouseupи keyupфункциям , поэтому .off()метод не удаляет другие слушателей , которые могут быть в игре.


Протестировано в IE 10+, FF 28+ и Chrome 35+


В качестве альтернативы, если вы хотите расширить jQuery с помощью функции, onceкоторая будет запускаться ровно один раз для любого количества событий :

$.fn.once = function (events, callback) {
    return this.each(function () {
        var myCallback = function (e) {
            callback.call(this, e);
            $(this).off(events, myCallback);
        };
        $(this).on(events, myCallback);
    });
};

Тогда вы можете упростить код так:

$("input").focus(function(){
    $(this).once("click keyup", function(e){      
        $(this).select();
    });
});

Демо в скрипке

KyleMit
источник
В Firefox 31 для Windows ваш код выделяет текст только при каждом щелчке, когда вы щелкаете между двумя текстовыми полями
Vitani
1
@Jocie, я не уверен, почему это чередуется, но похоже, что FF обрабатывает выделение текста в clickсобытии, которое находится дальше по конвейеру, чем mouseup. Так как мы хотим обработать конец выделения как можно позже, чтобы дать нам больше шансов переопределить браузер, использование click вместо mouseup должно помочь. Протестировано в FF, Chrome и IE.
KyleMit
1
Спасибо! Наконец-то решение, которое действительно работает и во всех браузерах!
Винсент
1
Да! Это сработало и для меня! Спасибо. Это должен был быть официальный ответ
Fandango68
1
@RiZKiT, oneне будет вырезать его как «Обработчик выполняется один раз для каждого элемента для каждого типа события . Он автоматически отключит событие, которое его вызвало, но другой все равно будет задерживаться и offв любом случае позаботится об обоих. вопрос: функция, которая будет срабатывать ровно один раз для любого количества событий
KyleMit
13

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

$("input[type=text]").click(function() {
    if(!$(this).hasClass("selected")) {
        $(this).select();
        $(this).addClass("selected");
    }
});
$("input[type=text]").blur(function() {
    if($(this).hasClass("selected")) {
        $(this).removeClass("selected");
    }
});
Nianpeng
источник
1
Важно сохранить возможность выделения части текста с помощью мыши. Я использую это и его A1
Филибер Perusse
2
Слишком много здесь происходит, используйте решение фокусировки /
Джордж
@George user2072367 довольно хорош, но у него есть серьезные недостатки. Проверьте мое решение (:
animatedgif
6

Эта версия работает на IOS, а также исправляет стандартное перетаскивание для выбора на Windows Chrome

var srcEvent = null;

$("input[type=text],input[type=number]")

    .mousedown(function (event) {
        srcEvent = event;
    })

    .mouseup(function (event) {
        var delta = Math.abs(event.clientX - srcEvent.clientX) 
                  + Math.abs(event.clientY - srcEvent.clientY);

        var threshold = 2;
        if (delta <= threshold) {
                   try {
                        // ios likes this but windows-chrome does not on number fields
                        $(this)[0].selectionStart = 0;
                        $(this)[0].selectionEnd = 1000;
                    } catch (e) {
                        // windows-chrome likes this
                        $(this).select();
                    }
        }
    });

http://jsfiddle.net/Zx2sc/2/

anihilnine
источник
Отредактировано, чтобы добавить некрасивую попытку / поймать, чтобы успокоить браузеры
anihilnine
5

Проблема большинства этих решений заключается в том, что они не работают правильно при изменении положения курсора в поле ввода.

onmouseupСобытие изменяет положение курсора в пределах поля, которое обжигало после того, как onfocus(по крайней мере , в пределах Chrome и FF). Если вы безоговорочно откажетесь, mouseupпользователь не сможет изменить положение курсора с помощью мыши.

function selectOnFocus(input) {
    input.each(function (index, elem) {
        var jelem = $(elem);
        var ignoreNextMouseUp = false;

        jelem.mousedown(function () {
            if (document.activeElement !== elem) {
                ignoreNextMouseUp = true;
            }
        });
        jelem.mouseup(function (ev) {
            if (ignoreNextMouseUp) {
                ev.preventDefault();
                ignoreNextMouseUp = false;
            }
        });
        jelem.focus(function () {
            jelem.select();
        });
    });
}
selectOnFocus($("#myInputElement"));

Код будет условно предотвращать mouseupповедение по умолчанию, если поле в данный момент не имеет фокуса. Это работает для этих случаев:

  • щелчок, когда поле не сфокусировано
  • щелчок, когда поле имеет фокус
  • вкладка в поле

Я проверил это в Chrome 31, FF 26 и IE 11.

Колин Брим
источник
Это прекрасно работает для событий щелчка, но если я использую вкладку для перехода к следующему полю ввода, я вижу, что контент выбирается и
отменяется
4

Нашел отличное решение, читая эту тему

$(function(){

    jQuery.selectText('input:text');
    jQuery.selectText('input:password');

});

jQuery.extend( {
    selectText: function(s) { 
        $(s).live('focus',function() {
            var self = $(this);
            setTimeout(function() {self.select();}, 0);
        });
    }
});
RafaelTSCS
источник
... что по сути тот же ответ, что и Писквор .
Оливер
не забывайте обо всех других типах текста HTML5, например, 'input [type = email]'
jamiebarrow
3

Я работаю в конце 2016 года, и этот код работает только в последних версиях jquery (в данном случае jquery-2.1.3.js).

if ($(element).is("input")) {
    $(element).focus(function () {
        $(element).select();
    });
}
Аарон
источник
2

Я использовал FF 16.0.2 и jquery 1.8.3, весь код в ответ не работал.
Я использую такой код и работаю.

$("input[type=text]").focus().select();
GusDeCooL
источник
4
Это не отвечает на вопрос, как выбрать содержимое поля ввода, когда пользователь фокусирует поле . Это сразу же сфокусирует и выберет код без ввода пользователя.
приветствие
@saluce я не понимаю, что ты имеешь в виду? что спрашивающий хочет, когда он выбирает поле, весь текущий текст выделяется. И мой код должен это сделать. Я даже использую его для своего проекта, как время, когда я пишу этот ответ.
GusDeCooL
1
Этот код будет фокусироваться и выделять все при запуске, но сам по себе код не привязан к пользовательскому событию , такому как нажатие на текстовое поле. Например, $("input[type=text]").on('click', function () { $(this).focus.select(); })вызывает фокусировку и делает выбор, когда пользователь щелкает окно, потому что оно выполняется, когда пользователь щелкает окно. Без обработчика событий код не отвечает на вопрос, а следовательно, понижает голос и комментирует. По сути, вы получили «весь текущий текст выделен», а не «когда он выбирает поле».
приветствие
1
@GusDeCooL, как ни странно (хотя это не совсем то, что он просил), я хотел получить тот же результат, что и вы :)
Робби Аверилл,
2
var timeOutSelect;
$("input[type=text]").focus(function() { 
        var save_this = $(this);
        clearTimeout(timeOutSelect);
        timeOutSelect = window.setTimeout (function(){ 
                save_this.select(); 
        }, 100);
});

Используйте clearTimeout для большей безопасности, если вы быстро переключаетесь между двумя входами .. clearTimeout очищает старое время ожидания ...

Азимов
источник
Пожалуйста, отредактируйте с дополнительной информацией. Ответы «только код» и «попробуй это» не приветствуются, потому что они не содержат контента для поиска и не объясняют, почему кто-то должен «попробовать это». Мы прилагаем все усилия, чтобы быть источником знаний.
Брайан Томпсетт - 莱恩 莱恩
2

Прекрасно работает с нативным JavaScript select().

$("input[type=text]").focus(function(event) {
   event.currentTarget.select();
});

или вообще:

$("input[type=text]")[0].select()
Тоби Г.
источник
1

Или вы можете просто использовать <input onclick="select()">Works отлично.

tectiv3
источник
нет, это не так. это работает для выбора целого. но попробуйте выделить часть текста вручную, вы не сможете это сделать.
Суджай Пхадке
1

Вы можете использовать простой код:

$('#idname').select();
Рубен Руис
источник
С использованием jQuery очевидно
Рубен Руис
0
<script>$.ready( $("input[type=text]").attr("onclick" , "this.select()"));<script>
trikon
источник
Вероятно, это будет помечено как некачественный ответ, поскольку в нем нет объяснения того, что происходит.
tumultous_rooster
Вы $.readyне правильно. Вам нужно передать ему функцию, чтобы она задерживала attrдо тех пор, пока документ не будет готов. Вы делаете это немедленно, а затем передаете коллекцию элементов в $.ready.
doug65536
Кроме того, избегайте «onclick», особенно таким образом. Использование addEventListener.
doug65536
0

Я всегда использую, requestAnimationFrame()чтобы перепрыгнуть через внутренние механизмы после события, и это отлично работает в Firefox. Не тестировался в Chrome.

$("input[type=text]").on('focus', function() {
    requestAnimationFrame(() => $(this).select());
});
Р.П. Педраса
источник