2011-02-03 14 views
11

Próbuję określić przepływ pracy, aby dostosować aplikację internetową do wprowadzania danych. Obraz kilka form adres na jednej stronie internetowej:jQuery przekazanie fokusa i kliknięcie elementu

1. Name___________ 
    Street_________ 
    Phone__________ 

    2. Name___________ 
    Street_________ 
    Phone__________ 

    [...many more...] 

teraz chciałbym wiedzieć, czy użytkownik korzysta z klawisza TAB, aby przejść do drugiego pola „Nazwa” (lub gdziekolwiek w tej płyty), lub jeśli używają myszy do kliknięcia. (Lub Shift-Tab, aby poruszać się w odwrotnej kolejności).

mam ustawić obsługi zarówno ostrość i kliknij na polach wejściowych:

$('input').click(function() { TabulateClick(this) }); 
$('input').focus(function() { TabulateFocus(this) }); 

I w uchwycie, określić, które rozwiązanie jest użytkownik praca nad i czy "przełączyliśmy" rekordy adresów. (W przypadku skupiono się na „telefon” dla pierwszego adresu i kliknięciu w polu „Nazwa” w samym adresem, to nie faktycznie przełączania płyt, więc nie tabularyzować że.)

function TabulateClick(field) 
    { 
     var currentAddressRecord = FindAddress(field); 
     if (lastAddressRecord != currentAddressRecord) 
      switchedAddressesWithClick++; 
     lastAddressRecord = currentAddress; 
    } 
    function TabulateFocus(field) 
    { 
     var currentAddress = FindAddress(field); 
     if (lastAddressRecord != currentAddressRecord) 
      switchedAddressesWithTab++; 
     lastAddressRecord = currentAddress; 
    } 

Mój problem polega na tym, że po kliknięciu myszą w polu zdarzenie focus uruchamia się najpierw w tabulacji fałszywego switchedAddressesWithTab i zmienia bieżący adres (to jest zły). Po uruchomieniu obsługi click urządzenie lastAddressRecord jest zepsute.

Czy istnieje sposób wewnątrz instrukcji obsługi focus, aby wiedzieć, że istnieje oczekujące zdarzenie click na tym samym obiekcie? Lub w obsłudze click, aby wiedzieć, że wcześniej była ona obsługiwana tylko przez focus?

Odpowiedz

15

Oto coś, co myślę, że prace w oparciu o fakt, że mouseDown dzieje się przed naciskiem. Zobacz demo.

var lastClick = null; 
$('input').mousedown(function(e) { 
    lastClick = e.target; 
}).focus(function(e){ 
    if (e.target == lastClick) { 
     console.log('click'); 
    } else { 
     console.log('tab');  
    } 
    lastClick = null; 

}); 

Aby naprawić błąd znaleziony przez Josiaha, zmieniłem kod na niższy. Zobacz demo.

var lastFocusedElement = null; 
var isClick = false; 
$('input').mousedown(function(e) {  
    isClick= true; 
}).focus(function(e){ 

    // To prevent focus firing when element already had focus 
    if (lastFocusedElement != e.target) { 
     if (isClick) { 
      console.log('click ----'); 
     } else { 
      console.log('tab -----');  
     } 
     lastFocusedElement = e.target; 
     isClick = false; 
    } 
}); 

$(document.body).focus(function(){ 
    lastFocusedElement = document.body; 
}); 

Problem polega na tym, że po przełączeniu się z okna i przełączeniu nie uzyskuje się "kliknięcia" ani tabulatora. Dostajesz fokus na wejściu, na którym ustawiono ostrość, ale nie możesz określić, czy jest to karta czy kliknięcie, ponieważ to nie jest żadna z nich.

Myślę, że jest to najbliższy wynik, spróbuję tego na twojej stronie i zobaczę, czy to zachowanie jest wystarczająco dobre.

+0

@Juan - od kiedy jesteśmy dzisiaj w QA, kiedy przechodzisz przez wszystkie pola do ciała, kliknij w jedno kliknięcie logów konsoli, zakładka –

+0

@Josiah: Dobry połów, nie rozumiem, dlaczego tak się dzieje .. Wydaje mi się, że dostarczyliśmy OP dwa sposoby, które działają przez większość czasu, wciąż inwestując kolejne 2 minuty w to, ale –

+0

@Juan - yah dzięki za rozmowę z moim spędzeniem więcej czasu niż kiedykolwiek przewidziałem na to pytanie;) co możemy do zrobienia, dang developerzy. –

0

Po prostu połącz fokus, a następnie sprawdź zdarzenie, aby zobaczyć, czy jest to e.which == 9 // tab.

Mój oryginalny pomysł nie zadziałał (dzięki @Juan). Korzystanie z kombinacji wydarzeń powinno doprowadzić cię tam, gdzie chcesz być. Jeśli użytkownik kliknie w polu tekstowym, ostatnie naciśnięcie klawisza nie będzie zakładką. Wszystkie wejścia oglądają i przechowują ostatni klucz, który należy przekazać do zdarzenia fokusa. here is the fiddle

var lastKeyCode = 0; 
$('input').focus(function(e) { 
    if(lastKeyCode == 9) 
     // tabbed into field 
    else 
     // clicked into field 
}).keydown(function(e){ 
    if(e.which == 9) // added timeout to clear lastkeypress 
     setTimeout(function(){lastKeyPress = 0}, 50); 
    lastKeyPress = e.which; // store last key code 
}); 
+0

mmm, bardzo interesujące, czy to jest testowane? –

+0

@Josiah: Nie sądzę, żeby to zadziałało - w FF mam niezdefiniowane, nawet jeśli wejdę na pole. –

+0

Nie działa: http://jsfiddle.net/3py9V/. Jeśli sugerujesz coś, co nie zostało przetestowane, powinieneś wspomnieć, że twoja odpowiedź jest nieprzetestowaną sugestią –

2

Można użyć metody .on() w jQuery. Oto inny sposób wiązania obu zdarzeń na tym samym elemencie.

var hasClicked = false; 
$('.myinputfield').on('mousedown : click',function(e){ 
    if (e.type == 'mousedown') { 
     // execute code 
     hasClicked = true; 
    } 
    if(e.type == 'focus' && !hasClicked) { 
     //execute code 
     console.log(e.type) 
    } 
    hasClicked = false; 
}); 
Powiązane problemy