Как узнать, какой элемент DOM имеет фокус?

Я хотел бы узнать на JavaScript, какой элемент в данный момент имеет фокус. Я просмотрел DOM и пока не нашел то, что мне нужно. Есть ли способ сделать это и как?

Причина, по которой я искал это:

Я пытаюсь заставить клавиши, такие как стрелки и enter перемещаться по таблице элементов ввода. Tab работает сейчас, но enter и стрелки не работают по умолчанию, как кажется. Я настроил обработку клавиш, но теперь мне нужно понять, как переместить фокус в функции обработки событий.

Комментарии к вопросу (1)
Решение

Используйте document.activeElement, он поддерживается во всех основных браузерах.

Раньше, если вы пытались узнать, какое поле формы имеет фокус, вы не могли этого сделать. Чтобы эмулировать обнаружение в старых браузерах, добавьте обработчик события "фокус" для всех полей и запишите последнее сфокусированное поле в переменную. Добавьте обработчик "blur", чтобы очистить переменную при наступлении события blur для последнего сфокусированного поля.

Похожие ссылки:

Комментарии (11)

Как сказал JW, вы не можете найти текущий сфокусированный элемент, по крайней мере, независимым от браузера способом. Но если ваше приложение работает только в IE (а некоторые работают...), вы можете найти его следующим способом:

document.activeElement

EDIT: Похоже, что в IE не все так плохо, в конце концов, это часть проекта HTML5 и, похоже, поддерживается последними версиями Chrome, Safari и Firefox, по крайней мере.

Комментарии (8)

Если вы можете использовать jQuery, теперь он поддерживает :фокус, просто убедитесь, что вы используете версию 1.6+.

Эта инструкция поможет вам текущему элементу.

$(":focus")

От: https://stackoverflow.com/questions/516152/how-to-select-an-element-that-has-focus-on-it-with-jquery/2061798#2061798

Комментарии (1)

документ.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 .

Комментарии (0)

Сам по себе документ.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;
});

Вы могли бы исправить исходное состояние предположения с помощью не событийными, но тогда вы могли бы также просто использовать это вместо этого.

Комментарии (0)

документ.activeElement может по умолчанию в <тело> элемент, если нет фокусируемые элементы в фокусе. Кроме того, если элемент находится в фокусе и окно браузера расплывается, activeElement продолжат удерживать сфокусированный элемент.

Если любой из этих двух поведений не желательно, рассмотрим УСБ-ориентированного подхода: документ.querySelector( &#39;:в центре внимания&#39; ).

Комментарии (2)

Мне понравился подход, используемый Джоэл, но я также люблю простоту документ.activeElement. Я использовал jQuery и объединил два. Старых браузерах, что Дон&#39;т поддерживать документ.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);
Комментарии (2)

Маленький помощник, что я'вэ, используемыми для этих целей в 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()` был призван на данного элемента.

Комментарии (0)

Библиотека jQuery поддерживает :фокус псевдо-класс, как тока. Если вы ищете его в jQuery документации, проверить Под на "селекторы", где он указывает вам на [CSS от W3C документацию][1]. Я&#39;вэ проверял С хрома, ФФ и IE 7+ и выше. Обратите внимание, что для того, чтобы работать в IE, в<!Тип документа... должны существовать на HTML-странице. Вот пример, предполагая, что вы'вэ присвоен ID к элементу, который имеет фокус:

$(":focus").each(function() {
  alert($(this).attr("id") + " has focus!");
});
Комментарии (1)

Если вы хотите получить объект, который является экземпляром элемент``, необходимо использоватьдокумент.activeElement, но если вы хотите получить объект, который является экземпляром ``текст``, вы должны использоватьдокумент.getSelection().focusNode``.

Я надеюсь, что помогает.

Комментарии (11)

Существуют потенциальные проблемы с помощью документа.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;
  }
}
Комментарии (1)

Если вы're, используя jQuery, вы можете использовать это, чтобы выяснить, если элемент является активным:

$("input#id").is(":active");
Комментарии (0)

Читая другие ответы, и пытался разобраться в себе, он кажется документе.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
  });
}
Комментарии (0)

С Dojo, вы можете использовать в dijit.getFocus()

Комментарии (0)

Я нашел следующий фрагмент кода будет полезно, когда пытаются определить, какой элемент в данный момент имеет фокус. Скопируйте следующий текст в консоли вашего браузера, и каждую секунду он будет выводить информацию о текущем элементе, который имеет фокус.

setInterval(function() { console.log(document.querySelector(":focus")); }, 1000);

Не стесняйтесь модифицировать консоль.войдите в журнал что-то другое, чтобы помочь вам точно определить элемент, если распечатать весь элемент не поможет вам определить элемент.

Комментарии (0)

Просто помещаю это здесь, чтобы дать решение, к которому я в итоге пришел.

Я создал свойство document.activeInputArea, использовал аддон jQuery's HotKeys для перехвата событий клавиатуры для клавиш со стрелками, tab и enter, а также создал обработчик событий для щелчков по элементам ввода.

Затем я настраивал activeInputArea при каждом изменении фокуса, чтобы использовать это свойство для определения своего местоположения.

Однако все это легко испортить, потому что если в системе есть ошибка и фокус находится не там, где вы думаете, то очень трудно восстановить правильный фокус.

Комментарии (0)