Po dokładnej analizie proponuję to jako znacznie czystsze rozwiązanie w tym wątku:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
Problem:
Oto kilka wyjaśnień:
Najpierw rzućmy okiem na kolejność zdarzeń, gdy klikniesz myszką lub tabulujesz w polu.
Możemy zarejestrować wszystkie odpowiednie zdarzenia w następujący sposób:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
Uwaga : Zmieniłem to rozwiązanie tak, aby używało, click
a nie mouseup
jak ma to miejsce później w potoku zdarzeń i wydawało się, że powoduje pewne problemy w firefoxie zgodnie z komentarzem @ Jocie
Niektóre przeglądarki próbują ustawić kursor podczas mouseup
click
zdarzeń lub . Ma to sens, ponieważ możesz uruchomić kursor w jednej pozycji i przeciągnąć, aby podświetlić jakiś tekst. Nie może oznaczać pozycji karetki, dopóki nie podniesiesz myszy. Funkcje, które obsługują, focus
są przeznaczone, aby reagować zbyt wcześnie, pozostawiając przeglądarkę nadpisującą twoje pozycjonowanie.
Ale pocieranie polega na tym, że naprawdę chcemy obsłużyć zdarzenie skupiające. Daje nam znać, kiedy ktoś wszedł na boisko po raz pierwszy. Po tym momencie nie chcemy nadal zastępować zachowań związanych z wyborem użytkownika.
Rozwiązanie:
Zamiast tego, w focus
module obsługi zdarzeń, możemy szybko dołączyć detektory zdarzeń click
(kliknięcie) i keyup
(tab in), które mają zostać uruchomione.
Uwaga : Keyup zdarzenia tab będzie faktycznie uruchamiane w nowym polu wejściowym, a nie w poprzednim
Chcemy odpalić wydarzenie tylko raz. Możemy użyć .one("click keyup)
, ale wywołałoby to obsługę zdarzeń jeden raz dla każdego typu zdarzenia . Zamiast tego, jak tylko naciśniemy przycisk myszy lub przycisk klawiatury, wywołamy naszą funkcję. Pierwszą rzeczą, którą zrobimy, jest usunięcie programów obsługi obu. W ten sposób nie będzie miało znaczenia, czy włożyliśmy tabulator, czy wtargnęliśmy. Funkcja powinna zostać wykonana dokładnie raz.
Uwaga : większość przeglądarek naturalnie zaznacza cały tekst podczas zdarzenia na karcie, ale jak zauważył animatedgif , nadal chcemy obsłużyć to keyup
zdarzenie, w przeciwnym mouseup
razie wydarzenie będzie się utrzymywać za każdym razem, gdy będziemy w nim zakładać. Słuchamy obu, abyśmy mogli włączyć od słuchaczy, jak tylko przetworzymy wybór.
Teraz możemy zadzwonić select()
po dokonaniu wyboru przeglądarki, więc z pewnością zastąpimy domyślne zachowanie.
Wreszcie, dla dodatkowej ochrony, możemy dodać przestrzenie nazw zdarzeń do funkcji mouseup
i, keyup
aby .off()
metoda nie usuwała żadnych innych detektorów, które mogłyby być w grze.
Testowane w IE 10+, FF 28+ i Chrome 35+
Alternatywnie, jeśli chcesz rozszerzyć jQuery o wywołaną funkcję once
, która uruchomi się dokładnie raz dla dowolnej liczby zdarzeń :
$.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);
});
};
Następnie możesz uprościć kod w następujący sposób:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});