Jak dowiedzieć się, który element DOM ma focus?
Chciałbym się dowiedzieć, w JavaScript, który element ma obecnie focus. Przeglądałem DOM i nie znalazłem jeszcze tego, czego potrzebuję. Czy jest na to sposób i jak?
Powód, dla którego tego szukałem:
Staram się, aby klawisze takie jak Strzałki i enter
poruszały się po tabeli elementów wejściowych. Zakładka działa teraz, ale wejść, i strzałki nie domyślnie wydaje. Mam ustawioną część obsługi klucza, ale teraz muszę wymyślić, jak przesunąć ostrość over w funkcjach obsługi zdarzeń.
16 answers
Użycie document.activeElement
, jest on obsługiwany we wszystkich głównych przeglądarkach.
Poprzednio, jeśli próbowałeś dowiedzieć się, które pole formularza ma fokus,nie mogłeś. Aby emulować wykrywanie w starszych przeglądarkach, dodaj obsługę zdarzenia "focus" do wszystkich pól i zapisz ostatnio ustawione pole w zmiennej. Dodaj funkcję obsługi "rozmycie", aby wyczyścić zmienną po zdarzeniu rozmycia dla Ostatnio ustawionego pola.
Powiązane linki:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-23 14:39:34
Jak 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żna go znaleźć w następujący sposób:
document.activeElement
EDIT: wygląda na to, że IE nie miało wszystkiego źle, jest to część HTML5 draft i wydaje się być wspierany przez najnowszą wersję Chrome, Safari i Firefox przynajmniej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-18 16:50:50
Jeśli możesz używać jQuery, obsługuje teraz :focus, tylko upewnij się, że używasz wersji 1.6+.
To polecenie spowoduje wyświetlenie aktualnie skupionego elementu.
$(":focus")
From: Jak wybrać element, który ma na nim fokus za pomocą jQuery
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:28
document.activeElement
jest teraz częścią projektu roboczego HTML5 specyfikacji, ale może nie być jeszcze obsługiwany w niektórych innych / mobilnych / starszych przeglądarkach. Możesz wrócić do querySelector
(jeśli jest to obsługiwane). Warto również wspomnieć, że document.activeElement
zwróci document.body
Jeśli żaden element nie jest fokusowany - nawet jeśli okno przeglądarki nie ma Fokusa.
Poniższy kod będzie działał wokół tego problemu i powróci do querySelector
dając nieco lepsze wsparcie.
var focused = document.activeElement;
if (!focused || focused == document.body)
focused = null;
else if (document.querySelector)
focused = document.querySelector(":focus");
Dodatkiem do notki jest różnica wydajności między tymi dwoma metodami. Odpytywanie dokumentu za pomocą selektorów zawsze będzie znacznie wolniejsze niż uzyskiwanie dostępu do właściwości activeElement
. Zobacz to jsperf.com test .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-19 13:01:06
Sam w sobie, document.activeElement
może nadal zwracać element, jeśli dokument nie jest skupiony (a więc nic w dokumencie nie jest skupione!)
Ty możesz chcieć takiego zachowania, lub to Może nie mieć znaczenia (np. w ramach zdarzenia keydown
), ale jeśli chcesz wiedzieć, że coś jest rzeczywiście skupione, możesz dodatkowo sprawdzić document.hasFocus()
.
Poniżej znajdziesz element skupiony, jeśli taki istnieje, lub null
.
var focused_element = null;
if (
document.hasFocus() &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
) {
focused_element = document.activeElement;
}
Aby sprawdzić, czy konkretny element ma fokus, jest prostszy:
var input_focused = document.activeElement === input && document.hasFocus();
Aby sprawdzić, czy cokolwiek jest skupione, to znowu jest bardziej złożone:
var anything_is_focused = (
document.hasFocus() &&
document.activeElement !== null &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
);
Uwaga solidności: w kodzie, w którym sprawdza się przed document.body
i document.documentElement
, dzieje się tak dlatego, że niektóre przeglądarki zwracają jedną z nich lub null
, gdy nic nie jest skupione.
Nie wyjaśnia, czy <body>
(a może <html>
) miał atrybut tabIndex
, a zatem Może być faktycznie skupiony . Jeśli jesteś pisząc bibliotekę lub coś i chcesz, aby była solidna, prawdopodobnie powinieneś sobie z tym jakoś poradzić.
Oto ( heavy airquotes) "one-liner" wersja getting The focused element, która jest koncepcyjnie bardziej skomplikowana , ponieważ musisz wiedzieć o zwarciu, a wiesz, to oczywiście nie pasuje do jednej linii, zakładając, że chcesz, aby było czytelne.
Nie polecam tego. Ale jeśli jesteś 1337 hax0r, idk... jest tam.
Mógłbyś usuń również || null
część, jeśli nie masz nic przeciwko temu, aby uzyskać false
w niektórych przypadkach. (Można jeszcze dostać null
Jeśli document.activeElement
jest null
):
var focused_element = (
document.hasFocus() &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement &&
document.activeElement
) || null;
Aby sprawdzić, czy dany element jest skupiony, alternatywnie można użyć zdarzeń, ale w ten sposób wymaga konfiguracji (i potencjalnie tearddown), i co ważne, przyjmuje stan początkowy :
var input_focused = false;
input.addEventListener("focus", function() {
input_focused = true;
});
input.addEventListener("blur", function() {
input_focused = false;
});
Możesz naprawić początkowe założenie stanu, używając Nie-eventowego sposobu, ale równie dobrze możesz użyć tego zamiast tego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-01 22:29:10
document.activeElement
może być domyślnym elementem <body>
, jeśli nie ma elementów fokusowalnych. Dodatkowo, jeśli element jest skupiony, a okno przeglądarki jest zamazane, activeElement
będzie nadal trzymać element skupiony.
Jeśli jedno z tych dwóch zachowań nie jest pożądane, rozważ podejście oparte na CSS: document.querySelector( ':focus' )
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-06 19:32:17
Podobało mi się podejście stosowane przez Joela S, ale uwielbiam też prostotę document.activeElement
. Użyłem jQuery i połączyłem te dwa. Starsze przeglądarki, które nie obsługują document.activeElement
, będą używać jQuery.data()
do przechowywania wartości 'hasFocus'. Nowsze przeglądarki będą używać document.activeElement
. Zakładam, że document.activeElement
będzie miał lepszą wydajność.
(function($) {
var settings;
$.fn.focusTracker = function(options) {
settings = $.extend({}, $.focusTracker.defaults, options);
if (!document.activeElement) {
this.each(function() {
var $this = $(this).data('hasFocus', false);
$this.focus(function(event) {
$this.data('hasFocus', true);
});
$this.blur(function(event) {
$this.data('hasFocus', false);
});
});
}
return this;
};
$.fn.hasFocus = function() {
if (this.length === 0) { return false; }
if (document.activeElement) {
return this.get(0) === document.activeElement;
}
return this.data('hasFocus');
};
$.focusTracker = {
defaults: {
context: 'body'
},
focusedElement: function(context) {
var focused;
if (!context) { context = settings.context; }
if (document.activeElement) {
if ($(document.activeElement).closest(context).length > 0) {
focused = document.activeElement;
}
} else {
$(':visible:enabled', context).each(function() {
if ($(this).data('hasFocus')) {
focused = this;
return false;
}
});
}
return $(focused);
}
};
})(jQuery);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 18:47:29
Mały pomocnik, którego używałem do tych celów w Mootools:
FocusTracker = {
startFocusTracking: function() {
this.store('hasFocus', false);
this.addEvent('focus', function() { this.store('hasFocus', true); });
this.addEvent('blur', function() { this.store('hasFocus', false); });
},
hasFocus: function() {
return this.retrieve('hasFocus');
}
}
Element.implement(FocusTracker);
W ten sposób można sprawdzić, czy element ma focus z el.hasFocus()
pod warunkiem, że startFocusTracking()
został wywołany na danym elemencie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-22 12:18:17
JQuery obsługuje pseudo-klasę :focus
od current. Jeśli szukasz go w dokumentacji JQuery, sprawdź w sekcji "selektory", gdzie wskazuje na W3C CSS docs. Testowałem z Chrome, FF i IE 7+. Zauważ, że aby działał w IE, <!DOCTYPE...
musi istnieć na stronie html. Oto przykład zakładając, że przypisałeś id do elementu, który ma focus:
$(":focus").each(function() {
alert($(this).attr("id") + " has focus!");
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-10 23:10:36
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
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-16 19:12:03
Istnieją potencjalne problemy z używaniem dokumentu.activeElement. Consider:
<div contentEditable="true">
<div>Some text</div>
<div>Some text</div>
<div>Some text</div>
</div>
Jeśli użytkownik skupia się na wewnętrznym-div, to document.activeElement nadal odwołuje się do zewnętrznego div. Nie można używać dokumentu.activeElement to determine which of the inner div ' s has focus.
Następująca funkcja obejdzie to i zwróci węzeł focused:
function active_node(){
return window.getSelection().anchorNode;
}
Jeśli wolisz uzyskać element skupiony, użyj:
function active_element(){
var anchor = window.getSelection().anchorNode;
if(anchor.nodeType == 3){
return anchor.parentNode;
}else if(anchor.nodeType == 1){
return anchor;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-01 07:36:58
Czytanie innych odpowiedzi i próba siebie, wydaje się document.activeElement
da ci element, którego potrzebujesz w większości przeglądarek.
Jeśli masz przeglądarkę, która nie obsługuje dokumentu.activeElement jeśli masz jQuery w pobliżu, powinieneś być w stanie wypełnić go na wszystkich zdarzeniach focus z czymś bardzo prostym, takim jak to (niesprawdzone, ponieważ nie mam przeglądarki spełniającej te kryteria): {]}
if (typeof document.activeElement === 'undefined') { // Check browser doesn't do it anyway
$('*').live('focus', function () { // Attach to all focus events using .live()
document.activeElement = this; // Set activeElement to the element that has been focussed
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-04 23:20:21
Jeśli używasz jQuery, możesz użyć tego, aby dowiedzieć się, czy element jest aktywny:
$("input#id").is(":active");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 19:29:01
Z dojo możesz używać dijit.getFocus ()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-13 11:55:48
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 jQuery ' s HotKeys addon do pułapek zdarzeń klawiatury dla klawiszy strzałek, tab i enter, i stworzyłem obsługę zdarzeń do klikania w elementy wejściowe.
Następnie dostosowałem activeInputArea za każdym razem, gdy zmieniałem ostrość, więc mogłem użyć tej właściwości, aby dowiedzieć się, gdzie jestem.
Łatwo to spieprzyć, bo jeśli masz błąd w system i ostrość nie jest tam, gdzie myślisz, że jest, to bardzo trudno jest przywrócić prawidłową ostrość.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-18 12:48:51
Poniższy fragment okazał się przydatny podczas próby określenia, który element ma aktualnie fokus. Skopiuj następujące elementy do konsoli przeglądarki, a co sekundę wydrukuje szczegóły bieżącego elementu, który ma fokus.
setInterval(function() { console.log(document.querySelector(":focus")); }, 1000);
Możesz zmodyfikować console.log
, aby wylogować coś innego, co pomoże Ci zlokalizować dokładny element, jeśli wydrukowanie całego elementu nie pomoże Ci zlokalizować elementu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-20 11:20:01