Chciałbym dowiedzieć się, w JavaScript, który element jest obecnie aktywny. Przeglądałem DOM i nie znalazłem jeszcze tego, czego potrzebuję. Czy jest na to sposób i jak to zrobić?
Powodem, dla którego tego szukałem:
Staram się tworzyć klucze takie jak strzałki i enter
nawigować w tabeli elementów wejściowych. Tab działa teraz, ale Enter, a strzałki domyślnie nie wydają się. Mam skonfigurowaną część do obsługi klucza, ale teraz muszę wymyślić, jak przenieść fokus w funkcjach obsługi zdarzeń.
javascript
dom
Tony Peterson
źródło
źródło
find-focused-element
pakietu: npmjs.com/package/find-focused-elementOdpowiedzi:
Użyj
document.activeElement
, jest obsługiwany we wszystkich głównych przeglądarkach.Poprzednio, jeśli próbowałeś dowiedzieć się, na czym skupia się pole formularza, nie mogłeś. Aby emulować wykrywanie w starszych przeglądarkach, dodaj moduł obsługi zdarzeń „focus” do wszystkich pól i zapisz pole, na którym ostatnio ustawiono ostrość, w zmiennej. Dodaj moduł obsługi „rozmycia”, aby wyczyścić zmienną po zdarzeniu rozmycia dla pola, na którym ostatnio ustawiono ostrość.
Jeśli chcesz usunąć
activeElement
, możesz użyć rozmycia;document.activeElement.blur()
. Zmieni toactiveElement
nabody
.Powiązane linki:
źródło
activeElement
faktycznie nie zwraca skupionego elementu. Dowolny element może być skoncentrowany. Jeśli dokument ma 4 „przewijane”, 0 lub 1 z tych div można przewijać za pomocą klawiszy strzałek. Jeśli klikniesz jeden, div zostanie skoncentrowany. Jeśli klikniesz poza wszystkim, ciało jest skupione. Jak dowiedzieć się, na czym skupia się scrolldiv? jsfiddle.net/rudiedirkx/bC5ke/show (sprawdź konsolę)div
jest Firefox 17 i tylko poprzez tabulator . Typy elementów, które zwracają WSZYSTKIE główne przeglądarki,document.activeElement
są ograniczone do elementów związanych z wprowadzaniem danych . Jeśli fokus nie ma takiego elementu, wszystkie główne przeglądarki zwracająbody
element - z wyjątkiem IE 9, który zwracahtml
element.document.activeElement
powinien być zawinięty,try catch
ponieważ w niektórych okolicznościach może generować wyjątek (nie tylko IE9 AFAIK). Zobacz bugs.jquery.com/ticket/13393 i bugs.jqueryui.com/ticket/8443Jak powiedział JW, nie można znaleźć bieżącego elementu skupionego, przynajmniej w sposób niezależny od przeglądarki. Ale jeśli twoja aplikacja jest tylko IE (niektóre są ...), możesz ją znaleźć w następujący sposób:
EDYCJA: Wygląda na to, że IE nie miał przecież wszystkiego źle, jest to część szkicu HTML5 i wydaje się być obsługiwane przez najnowszą wersję Chrome, Safari i Firefox.
źródło
Jeśli możesz korzystać z jQuery, obsługuje teraz: focus, upewnij się, że używasz wersji 1.6+.
To oświadczenie zapewni ci aktualnie skoncentrowany element.
Od: Jak wybrać element, który skupia się na nim za pomocą jQuery
źródło
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
document.activeElement
jest teraz częścią specyfikacji roboczej wersji HTML5 , ale może nie być jeszcze obsługiwany w niektórych przeglądarkach innych niż główne / mobilne / starsze. Możesz wrócić doquerySelector
(jeśli jest to obsługiwane). Warto również wspomnieć, żedocument.activeElement
zwróci się,document.body
jeśli żaden element nie jest skoncentrowany - nawet jeśli okno przeglądarki nie ma fokusa.Poniższy kod obejmie ten problem i wróci do
querySelector
nieco lepszego wsparcia.Dodatkową rzeczą, na którą należy zwrócić uwagę, jest różnica w wydajności między tymi dwiema metodami. Zapytanie o dokument za pomocą selektorów zawsze będzie znacznie wolniejsze niż uzyskiwanie dostępu do
activeElement
właściwości. Zobacz ten test jsperf.com .źródło
Sam w sobie
document.activeElement
może nadal zwracać element, jeśli dokument nie jest skoncentrowany (a zatem nic w dokumencie jest skoncentrowane!)Państwo może chcieć to zachowanie, albo może nie materia (np w
keydown
przypadku), ale jeśli chcesz wiedzieć coś jest rzeczywiście koncentruje można dodatkowo sprawdzićdocument.hasFocus()
.Poniższe informacje przedstawiają element skupiony, jeśli taki istnieje, lub inny element
null
.Aby sprawdzić, czy specyficzny element ma ostrość, to prostsze:
Aby sprawdzić, czy coś jest skoncentrowane, jest to znowu bardziej złożone:
Uwaga na temat niezawodności : w kodzie, w którym sprawdza on,
document.body
orazdocument.documentElement
dlatego, że niektóre przeglądarki zwracają jedną z nich lubnull
gdy nic nie jest skoncentrowane.Nie bierze pod uwagę, czy
<body>
(a może<html>
) miałtabIndex
atrybut, a zatem mógł się skupić . Jeśli piszesz bibliotekę lub coś i chcesz, aby była solidna, prawdopodobnie powinieneś jakoś sobie z tym poradzić.Oto ( jednokierunkowa) wersja ( ciężkie cytaty) uzyskiwania skupionego elementu, która jest koncepcyjnie bardziej skomplikowana, ponieważ musisz wiedzieć o zwarciach, a wiesz, oczywiście, że nie pasuje do jednej linii, zakładając, że chcę, żeby było czytelne.
Nie polecę tego. Ale jeśli masz 1337 hax0r, idk ... to tam jest.
Możesz również usunąć tę
|| null
część, jeślifalse
w niektórych przypadkach nie masz nic przeciwko . (Możesz nadal uzyskać,null
jeślidocument.activeElement
jestnull
):Do sprawdzania, czy element specyficzny koncentruje alternatywnie Państwo mogli użyć zdarzenia, ale w ten sposób wymaga konfiguracji (i potencjalnie porzuca), i co najważniejsze, zakłada stan początkowy :
Możesz naprawić założenie stanu początkowego, używając nie-zdarzeń, ale równie dobrze możesz po prostu użyć tego zamiast.
źródło
document.activeElement
może przyjmować wartość domyślną dla<body>
elementu, jeśli nie są aktywne żadne elementy, na które można ustawić ostrość. Dodatkowo, jeśli element jest skupiony, a okno przeglądarki jest rozmyte,activeElement
nadal będzie utrzymywał skupiony element.Jeśli któryś z tych dwóch zachowań nie są pożądane, należy rozważyć podejście oparte na CSS:
document.querySelector( ':focus' )
.źródło
querySelector
: stackoverflow.com/a/40873560/2624876Podobało mi się podejście zastosowane przez Joela S., ale lubię też prostotę
document.activeElement
. Użyłem jQuery i połączyłem oba. Starsze przeglądarki, które nie obsługują,document.activeElement
będą używaćjQuery.data()
do przechowywania wartości „hasFocus”. Będą używane nowsze przeglądarkidocument.activeElement
. Zakładam, żedocument.activeElement
będzie miał lepszą wydajność.źródło
$("*:focus")
?Mały pomocnik, którego użyłem do tych celów w Mootools:
W ten sposób możesz sprawdzić, czy element ma fokus
el.hasFocus()
pod warunkiem, żestartFocusTracking()
został wywołany na danym elemencie.źródło
JQuery obsługuje obecnie
:focus
pseudoklasę. Jeśli szukasz tego w dokumentacji JQuery, sprawdź w „Selektorach”, gdzie prowadzi do dokumentów W3C CSS . Testowałem z Chrome, FF i IE 7+. Pamiętaj, że aby działał w IE,<!DOCTYPE...
musi istnieć na stronie HTML. Oto przykład, zakładając, że przypisałeś identyfikator do elementu, który ma fokus:źródło
this.id
zamiast$(this).attr('id')
lub przynajmniej (kiedy już masz swój obiekt jQuery)$(this)[0].id
. Natywny Javascript na tym poziomie jest ZNACZNIE szybszy i bardziej wydajny. W tym przypadku może nie być zauważalny, ale w całym systemie zauważysz różnicę.Jeśli chcesz uzyskać obiekt, który jest instancją
Element
, musisz użyćdocument.activeElement
, ale jeśli chcesz uzyskać obiekt, który jest instancjąText
, musisz użyćdocument.getSelection().focusNode
.Mam nadzieję, że pomoże.
źródło
document.getSelection().focusNode.parentElement
i naciśnij Enter. Po tym, przeszłośćdocument.activeElement
i zrób to sametpling. ;)document.activeElement
daje<textarea>
natomiastdocument.getSelection().focusNode
daje<td>
, że zawiera<textarea>
(idocument.getSelection().focusNode.parentElement
daje<tr>
zawierający<td>
)Element
, musisz użyćdocument.activeElement
, ale jeśli chcesz uzyskać obiekt, który jest instancjąText
, musisz użyćdocument.getSelection().focusNode
. Sprawdź to jeszcze raz. Mam nadzieję, że pomogłem.focusNode
nie jest gwarancją węzłem tekstowym albo.Istnieją potencjalne problemy z użyciem document.activeElement. Rozważać:
Jeśli użytkownik skupia się na wewnętrznej div, wtedy document.activeElement nadal odwołuje się do zewnętrznej div. Nie możesz użyć document.activeElement, aby określić, który z wewnętrznych div ma fokus.
Obejdzie to następująca funkcja i zwróci skoncentrowany węzeł:
Jeśli wolisz uzyskać element skupiony, użyj:
źródło
document.activeElement
: wewnętrzne<div>
elementy w rzeczywistości nie mogą otrzymać fokusu, co można zobaczyć wizualnie, ustawiając:focus
pseudoklasę na coś widocznego (przykład: jsfiddle.net/4gasa1t2/1 ). Mówisz o tym, który z elementów wewnętrznych<div>
zawiera zaznaczenie lub kursor, co jest osobną kwestią.Uważam, że następujący fragment kodu jest przydatny podczas próby ustalenia, który element jest aktualnie aktywny. Skopiuj następujące elementy do konsoli przeglądarki, a co sekundę będą drukować szczegóły bieżącego elementu, który ma fokus.
Zmodyfikuj,
console.log
aby wylogować się z czegoś innego, co pomoże ci dokładnie określić element, jeśli wydrukowanie całego elementu nie pomoże w ustaleniu elementu.źródło
Czytanie innych odpowiedzi i samodzielne wypróbowanie
document.activeElement
daje ci element, którego potrzebujesz w większości przeglądarek.Jeśli masz przeglądarkę, która nie obsługuje document.activeElement, jeśli masz jQuery w pobliżu, powinieneś być w stanie wypełnić ją wszystkimi zdarzeniami fokusowymi czymś bardzo prostym, takim jak to (niesprawdzone, ponieważ nie mam przeglądarki spełniającej te kryteria ):
źródło
Jeśli używasz jQuery, możesz użyć tego, aby dowiedzieć się, czy element jest aktywny:
źródło
W dojo możesz użyć dijit.getFocus ()
źródło
Po prostu umieszczam to tutaj, aby dać rozwiązanie, które w końcu wymyśliłem.
Utworzyłem właściwość o nazwie document.activeInputArea i użyłem dodatku HotKeys jQuery'ego do przechwytywania zdarzeń klawiatury dla klawiszy strzałek, tab i enter, i utworzyłem moduł obsługi zdarzeń do klikania w elementy wejściowe.
Następnie dostosowywałem activeInputArea przy każdej zmianie fokusa, dzięki czemu mogłem użyć tej właściwości, aby dowiedzieć się, gdzie jestem.
Łatwo to jednak zepsuć, ponieważ jeśli masz błąd w systemie i fokus nie jest tam, gdzie myślisz, że jest, to bardzo trudno jest przywrócić prawidłowe fokus.
źródło