2011-02-04 4 views
27

Istnieją dwa elementy w grze:Działanie na rozmycie wyjątkiem sytuacji, gdy określony element kliknięty z jQuery

$('#myInput') // an input field for search 
$('#myList') // a list to display search results 

chcę ukryć listę, gdy na wejściu nie ma już skupić, tak jak poniżej:

$('#myInput').blur(function() { 
    $('#myList').hide(); 
}); 

Działa to znakomicie, z wyjątkiem sytuacji, gdy kliknięto element listy, ponieważ zdarzenie blur wywołuje i ukrywa listę przed zarejestrowaniem kliknięcia. Celem jest, aby lista pozostała widoczna po kliknięciu dowolnej części listy, nawet jeśli spowoduje to rozmycie wejścia.

Jak mogę to zrobić? Dzięki!

Odpowiedz

13

Można to osiągnąć poprzez utrzymanie zmienną globalną i setTimouts, aby odczekaj 200 ms, a następnie sprawdź, czy jeden z 2 elementów ma fokus.

var keepFocus = false; 

function hideList(){ 
    if(!keepFocus){ 
     $('#myList').hide(); 
    } 
} 

$('#myInput').blur(function() { 
    keepFocus = false; 
    window.setTimeout(hideList, 200); 
}).focus(function(){ 
    keepFocus = true; 
}); 


$('#myList').blur(function() { 
    keepFocus = false; 
    window.setTimeout(hideList, 200); 
}).focus(function(){ 
    keepFocus = true; 
}); 
+0

Rozmycie i fokus nie działają w przypadku #myList, ponieważ nie jest to wejście. –

+0

@Justin, co to jest? Spróbuj usunąć metodę 'focus' z listy i umieść kod' blur' na liście 'kliknij' zdarzenie –

+0

To tylko div. Zaadaptowałem Twój kod do pracy z moją konfiguracją, więc dziękuję! –

11

Musisz móc powiedzieć "zrób to rozmycie(), chyba że lista zyskuje ostrość w tym samym czasie".

To pytanie mówi w jaki sposób wykryć, czy element ma skupić: Using jQuery to test if an input has focus

Następnie wszystko co musisz zrobić, to:

$("#myInput").blur(function() { 
    if (!$("#myList").is(":focus")) { 
     $("#myList").hide(); 
    } 
}); 
+4

Nie wydaje się działać. document.activeElement pokazuje znacznik body jako element "focused". Zgaduję, że to nie działa, ponieważ idea "fokusu" jest nieodłącznie związana z polami wejściowymi. –

1

Najlepszym sposobem, aby to zrobić, aby dołączyć obsługi zdarzeń do elementu nadwozia, potem drugi teleskopowa do listy, która zatrzymuje propagacji zdarzenia:

$(body).click(function() { 
    $("#myList").hide(); 
}); 

$("#myList").click(function (e) { 
    e.stopImmediatePropagation(); 
}); 

Ten słucha za kliknięcie poza # myInput i ukrywa #myList. W tym samym czasie druga funkcja nasłuchuje kliknięcia na #myList, a jeśli wystąpi, uniemożliwia wypalenie hide().

+4

To ignoruje klawiaturę. Rozmycie jest wyzwalane, gdy pole jest zablokowane. –

7

Mam do czynienia z dokładnie ten sam problem, więc w ten sposób go rozwiązałem.

Wpadłem na pomysł, że blur() wystrzeli wcześniej niż click().

Więc próbowałem zmienić click() do mousedown() i okazało się, że mousedown() pożary przed blur().

I naśladować click() musisz odpalić mousedown() a następnie mouseup()

Więc w twoim przypadku chciałbym zrobić coś takiego:

var click_in_process = false; // global 

$('#myList').mousedown(function() { 
    click_in_process = true; 
}); 

$('#myList').mouseup(function() { 
    click_in_process = false; 
    $('#myInput').focus(); 

    // a code of $('#myList') clicking event 

}); 

$('#myInput').blur(function() { 
    if(!click_in_process) { 
     $('#myList').hide(); 

     // a code of what you want to happen after you really left $('#myInput') 

    } 
}); 

demo/przykład: http://jsfiddle.net/bbrh4/

Nadzieja to pomaga!

+1

Co się stanie, jeśli kolejność zdarzeń jest inna w określonej przeglądarce lub urządzeniu? Jeśli dobrze pamiętam, to zamówienie nie jest zdefiniowane. – Gherman

+1

@German To działało poprawnie na wszystkich urządzeniach i przeglądarkach, które miałem wtedy (jak pamiętam Chrome/Firefox/Opera/IE/iOS/Android/WP). Może coś się zmieniło, ale szczerze mówiąc wątpię w to. Ale jeśli masz na myśli jakiś konkretny przykład, będę bardzo szczęśliwy z tego powodu. A jeśli to prawda, polecam napisanie usługi/pomocnika/biblioteki, w której można wykonać różne logiki w zależności od bieżącej przeglądarki lub urządzenia. –

+1

Nie mam żadnych złych przykładów. Po prostu byłem bardzo ostrożny. Teoretycznie kolejność zdarzeń nie jest zdefiniowana w standardach. – Gherman