Я хотел бы узнать на JavaScript, какой элемент в данный момент имеет фокус. Я просмотрел DOM и пока не нашел то, что мне нужно. Есть ли способ сделать это и как?
Причина, по которой я искал это:
Я пытаюсь заставить клавиши, такие как стрелки и enter
перемещаться по таблице элементов ввода. Tab работает сейчас, но enter и стрелки не работают по умолчанию, как кажется. Я настроил обработку клавиш, но теперь мне нужно понять, как переместить фокус в функции обработки событий.
Используйте document.activeElement
, он поддерживается во всех основных браузерах.
Раньше, если вы пытались узнать, какое поле формы имеет фокус, вы не могли этого сделать. Чтобы эмулировать обнаружение в старых браузерах, добавьте обработчик события "фокус" для всех полей и запишите последнее сфокусированное поле в переменную. Добавьте обработчик "blur", чтобы очистить переменную при наступлении события blur для последнего сфокусированного поля.
Похожие ссылки:
Как сказал JW, вы не можете найти текущий сфокусированный элемент, по крайней мере, независимым от браузера способом. Но если ваше приложение работает только в IE (а некоторые работают...), вы можете найти его следующим способом:
document.activeElement
EDIT: Похоже, что в IE не все так плохо, в конце концов, это часть проекта HTML5 и, похоже, поддерживается последними версиями Chrome, Safari и Firefox, по крайней мере.
Если вы можете использовать jQuery, теперь он поддерживает :фокус, просто убедитесь, что вы используете версию 1.6+.
Эта инструкция поможет вам текущему элементу.
$(":focus")
документ.activeElementсейчас [часть работает на HTML5 проекта] спецификация(http://www.w3.org/TR/html5/editing.html#dom-document-activeelement), но это может не поддерживаться в некоторых неглавных/мобильный/старых браузерах. Вы можете вернуться к
querySelector(если это поддерживается). Это's также стоит отметить, что документ.activeElement
вернет `документ.тело-если бы не элемент фокусируется на — не Даже если окно браузера не'т иметь фокус.
Следующий код позволит обойти эту проблему и вернуться к querySelector
дает немного лучшую поддержку.
var focused = document.activeElement;
if (!focused || focused == document.body)
focused = null;
else if (document.querySelector)
focused = document.querySelector(":focus");
Кроме того, что следует отметить, это разница в производительности между этими двумя методами. Запрос документа с селекторами всегда будет намного медленнее, чем доступ к activeElement
собственность. Увидеть это тест jsperf.com .
Сам по себе документ.activeElement все еще может вернуть элемент, если документ не'т сосредоточился (и, следовательно, не в документе ориентирован!)
Вы можете хотите, что поведение, или он может не имеет значения (например, в вниз
событие), но если вам нужно что-то узнать на самом деле, можно дополнительно проверить документ.hasFocus()
.
Следующие даст вам сфокусированного элемента, если есть один, или еще нуль
.
var focused_element = null;
if (
document.hasFocus() &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
) {
focused_element = document.activeElement;
}
Чтобы проверить, является ли конкретные элемент имеет фокус, он'ы проще:
var input_focused = document.activeElement === input && document.hasFocus();
Чтобы проверить, является ли ничего - это целенаправленный, это's более сложные снова:
var anything_is_focused = (
document.hasFocus() &&
document.activeElement !== null &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
);
*Надежность Примечание**: в коде, где она проверяет против документа.тела " и " документ.функцию documentelement, это потому, что некоторые браузеры возвращают один из этих или
нуль`, когда ничего не ориентируется.
Это не'т на счет если в <тело>
(или, может быть, в <html-код>
) у атрибута tabindex В
и, следовательно, может на самом деле быть сфокусированным. Если вы'вновь пишу библиотеку или что-то и хочу, чтобы оно было надежным, вы должны, вероятно, справиться, что-то.
Здесь'ы (тяжелый airquotes) "один-вкладыш" по версии получения сфокусированного элемента, который концептуально сложнее потому что вы должны знать о короткое замыкание, и y'знаю, это явно не'т помещается в одну строку, если вы хотите, чтобы это было читабельно.
Я'м не буду рекомендовать этот отель. Но если вы'вновь в 1337 hax0r, ИДК... это's там.
Вы также можете удалить || значение null,
часть, если вы не'т ум становится false
в некоторых случаях. (Вы все еще можете сделать нуль
, если документ.activeElement
нулевой
):
var focused_element = (
document.hasFocus() &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement &&
document.activeElement
) || null;
Для проверки, если элемент находится в фокусе, либо вы можете использовать события, но этот способ требует установки (и потенциально разобрала), и главное, принимает исходное состояние:
var input_focused = false;
input.addEventListener("focus", function() {
input_focused = true;
});
input.addEventListener("blur", function() {
input_focused = false;
});
Вы могли бы исправить исходное состояние предположения с помощью не событийными, но тогда вы могли бы также просто использовать это вместо этого.
документ.activeElement может по умолчанию в <тело>
элемент, если нет фокусируемые элементы в фокусе. Кроме того, если элемент находится в фокусе и окно браузера расплывается, activeElement
продолжат удерживать сфокусированный элемент.
Если любой из этих двух поведений не желательно, рассмотрим УСБ-ориентированного подхода: документ.querySelector( ':в центре внимания' )
.
Мне понравился подход, используемый Джоэл, но я также люблю простоту документ.activeElement. Я использовал jQuery и объединил два. Старых браузерах, что Дон'т поддерживать документ.activeElement будет использовать в jQuery.данных()
для хранения значения 'hasFocus'. Новые браузеры будут использовать документ.activeElement. Я предполагаю, что
документ.activeElement будет иметь более высокую производительность.
(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);
Маленький помощник, что я'вэ, используемыми для этих целей в 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);
Таким образом, вы можете проверить, если элемент имеет фокус с эл.hasFocus()при условии
startFocusTracking()` был призван на данного элемента.
Библиотека jQuery поддерживает :фокус псевдо-класс, как тока. Если вы ищете его в jQuery документации, проверить Под на "селекторы", где он указывает вам на [CSS от W3C документацию][1]. Я'вэ проверял С хрома, ФФ и IE 7+ и выше. Обратите внимание, что для того, чтобы работать в IE, в
<!Тип документа... должны существовать на HTML-странице. Вот пример, предполагая, что вы'вэ присвоен ID к элементу, который имеет фокус:
$(":focus").each(function() {
alert($(this).attr("id") + " has focus!");
});
Если вы хотите получить объект, который является экземпляром элемент``, необходимо использовать
документ.activeElement, но если вы хотите получить объект, который является экземпляром ``текст``, вы должны использовать
документ.getSelection().focusNode``.
Я надеюсь, что помогает.
Существуют потенциальные проблемы с помощью документа.activeElement. Рассмотрим:
<div contentEditable="true">
<div>Some text</div>
<div>Some text</div>
<div>Some text</div>
</div>
Если пользователь ориентируется на внутренний div, а затем документ.activeElement по-прежнему ссылается на внешний див. Нельзя использовать документ.activeElement, чтобы определить, какой из внутренних дел's имеет фокус.
Следующая функция получает вокруг этого, и возвращает сфокусированного узла:
function active_node(){
return window.getSelection().anchorNode;
}
Если вы предпочитаете получить сфокусированный элемент, использовать с:
function active_element(){
var anchor = window.getSelection().anchorNode;
if(anchor.nodeType == 3){
return anchor.parentNode;
}else if(anchor.nodeType == 1){
return anchor;
}
}
Читая другие ответы, и пытался разобраться в себе, он кажется документе.activeElement даст вам элемент, который вы должны в большинстве браузеров.
Если у вас есть браузер, который не'документ поддержки T.activeElement если у вас есть библиотека jQuery, вы должны быть в состоянии заполнить его на все события фокуса с что-то очень простое вроде этого (непроверенных, как я Дон'Т есть браузер, удовлетворяющие этим критериям для рук):
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
});
}
С Dojo, вы можете использовать в dijit.getFocus()
Я нашел следующий фрагмент кода будет полезно, когда пытаются определить, какой элемент в данный момент имеет фокус. Скопируйте следующий текст в консоли вашего браузера, и каждую секунду он будет выводить информацию о текущем элементе, который имеет фокус.
setInterval(function() { console.log(document.querySelector(":focus")); }, 1000);
Не стесняйтесь модифицировать консоль.войдите в журнал что-то другое, чтобы помочь вам точно определить элемент, если распечатать весь элемент не поможет вам определить элемент.
Просто помещаю это здесь, чтобы дать решение, к которому я в итоге пришел.
Я создал свойство document.activeInputArea, использовал аддон jQuery's HotKeys для перехвата событий клавиатуры для клавиш со стрелками, tab и enter, а также создал обработчик событий для щелчков по элементам ввода.
Затем я настраивал activeInputArea при каждом изменении фокуса, чтобы использовать это свойство для определения своего местоположения.
Однако все это легко испортить, потому что если в системе есть ошибка и фокус находится не там, где вы думаете, то очень трудно восстановить правильный фокус.