Після ретельного огляду я пропоную це як набагато чистіше рішення в цій темі:
$("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
(натисніть) та keyup
(вкладка), які збираються запустити.
Примітка . Клавіатура події вкладки фактично запуститься в новому полі введення, а не в попередньому
Ми хочемо запустити подію лише один раз. Ми могли б використовувати .one("click keyup)
, але це викликало б обробник подій один раз для кожного типу події . Натомість, як тільки натискається клавіша миші або клавіатура, ми викликаємо нашу функцію. Перше, що ми зробимо - це видалити обробники для обох. Таким чином, не має значення, чи ми вкладали вкладки чи микали. Функція повинна виконуватися рівно один раз.
Примітка . Більшість браузерів, звичайно, вибирають увесь текст під час події на вкладці, але, як вказував анімографічний малюнок , ми все ще хочемо обробляти 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();
});
});