После тщательного рассмотрения я предлагаю это как более чистое решение в этой теме:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
Проблема:
Вот небольшое объяснение:
Сначала давайте посмотрим на порядок событий, когда вы наводите курсор мыши на поле или вкладку.
Мы можем регистрировать все соответствующие события следующим образом:
$("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), которыеготовность к запуску.
Примечание : при нажатии кнопки табуляции событие фактически срабатывает в новом поле ввода, а не в предыдущем
Мы хотим запустить событие только один раз.Мы можем использовать .one("click keyup)
, но это вызовет обработчик события один раз для каждого типа события .Вместо этого, как только будет нажата кнопка mouseup или keyup, мы вызовем нашу функцию.Первое, что мы сделаем, это удалим обработчики для обоих.Таким образом, не имеет значения, будем ли мы вкладывать или вставлять. Функция должна выполняться ровно один раз.
Примечание : большинство браузеров естественным образом выделяют весь текст во время события вкладки, нокак animatedgif указал , мы все еще хотим обработать событие keyup
, в противном случае событие mouseup
все еще будет задерживаться каждый раз, когда мы вкладываем вкладку. Мы слушаем оба, чтобы мы могли отключитьслушатели, как только мы обработали выделение.
Теперь мы можем вызвать select()
после того, как браузер сделал свой выбор, поэтому мы обязательно переопределим поведение по умолчанию.
Наконец, для дополнительной защиты мы можем добавить пространства имен событий к функциям mouseup
и keyup
, чтобы метод .off()
не удалял других слушателей, которые могли быбыть в игре.
Протестировано в IE 10+, FF 28+ и Chrome 35 +
В качестве альтернативы, если вы хотите расширить jQuery с помощью функции называется once
, который сработает ровно один раз для любого числа of events :
$.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();
});
});