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

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

Я искал это:

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

931
задан 30 янв. '09 в 23:21
источник поделиться
18 ответов

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

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

Ссылки по теме:

1083
ответ дан 30 янв. '09 в 23:24
источник

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

document.activeElement

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

100
ответ дан 30 янв. '09 в 23:34
источник

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

Этот оператор предоставит вам сосредоточенный в данный момент элемент.

$(":focus")

От: Как выбрать элемент, который сфокусирован на нем с помощью jQuery

73
ответ дан 27 авг. '11 в 20:33
источник

document.activeElement теперь часть спецификации HTML5 рабочего проекта, но она может еще не поддерживаться в некоторых браузерах, не поддерживающих основные/мобильные/старые. Вы можете вернуться к querySelector (если это поддерживается). Также стоит отметить, что document.activeElement вернет document.body, если ни один элемент не сфокусирован — даже если окно браузера не имеет фокуса.

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

var focused = document.activeElement;
if (!focused || focused == document.body)
    focused = null;
else if (document.querySelector)
    focused = document.querySelector(":focus");

Кроме того, следует отметить разницу в производительности между этими двумя методами. Запрос документа с помощью селекторов всегда будет намного медленнее, чем доступ к свойству activeElement. См. Этот тест jsperf.com.

36
ответ дан 19 окт. '11 в 16:01
источник

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

Если одно из этих двух вариантов поведения нежелательно, рассмотрите подход на основе CSS: document.querySelector( ':focus' ).

11
ответ дан 06 авг. '14 в 22:32
источник

Мне понравился подход, используемый Джоэлем С., но мне также нравится простота document.activeElement. Я использовал jQuery и объединил два. Старые браузеры, которые не поддерживают document.activeElement, будут использовать jQuery.data() для хранения значения 'hasFocus'. Новые браузеры будут использовать document.activeElement. Я предполагаю, что document.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);
10
ответ дан 08 сент. '10 в 21:47
источник

Небольшой помощник, который я использовал для этих целей в 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);

Таким образом вы можете проверить, имеет ли элемент фокус с el.hasFocus() при условии, что startFocusTracking() был вызван для данного элемента.

9
ответ дан 04 февр. '10 в 15:36
источник

JQuery поддерживает псевдо-класс :focus по сравнению с текущим. Если вы ищете его в документации JQuery, поставьте отметку в разделе "Селекторы", где он указывает на W3C CSS docs. Я тестировал Chrome, FF и IE 7+. Обратите внимание, что для работы в IE на странице html должен существовать <!DOCTYPE.... Вот пример, предполагающий, что вы присвоили идентификатор элементу с фокусом:

$(":focus").each(function() {
  alert($(this).attr("id") + " has focus!");
});
7
ответ дан 11 марта '11 в 2:10
источник

Существуют потенциальные проблемы с использованием document.activeElement. Рассмотрим:

<div contentEditable="true">
  <div>Some text</div>
  <div>Some text</div>
  <div>Some text</div>
</div>

Если пользователь фокусируется на внутреннем-div, тогда document.activeElement по-прежнему ссылается на внешний div. Вы не можете использовать document.activeElement, чтобы определить, какой из внутренних div имеет фокус.

Следующая функция обходит вокруг этого и возвращает сфокусированный node:

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;
  }
}
5
ответ дан 01 марта '15 в 10:36
источник

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

Если у вас есть браузер, который не поддерживает document.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
  });
}
5
ответ дан 05 авг. '11 в 2:20
источник

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

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

5
ответ дан 17 июля '16 в 8:52
источник

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

$("input#id").is(":active");
5
ответ дан 14 февр. '12 в 22:29
источник

Сам по себе document.activeElement может возвращать элемент, если документ не сфокусирован. Возможно, вы захотите этого поведения, но если вы этого не сделаете, вы можете проверить document.hasFocus():

var focused_element =
    document.hasFocus() &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement &&
    document.activeElement;

Чтобы проверить, имеет ли конкретный элемент фокус:

var input_focused = document.activeElement === input && document.hasFocus();

В качестве альтернативы вы можете использовать события, но для этого требуется установка и предполагается исходное состояние:

var input_focused = false;
input.addEventListener("focus", function() {
    input_focused = true;
});
input.addEventListener("blur", function() {
    input_focused = false;
});
5
ответ дан 29 нояб. '16 в 21:51
источник

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

4
ответ дан 13 янв. '12 в 14:55
источник

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

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

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

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

3
ответ дан 18 мая '09 в 15:48
источник

Почти независимый от браузера способ достичь этого был сделан Quirksmode давным-давно. У него могут быть проблемы с Safari, поскольку Safari не всегда устанавливает события на тех же элементах, что и Chrome или Firefox. Иногда Safari даже устанавливает событие на текстовое поле вместо содержащего элемента. Это может быть исправлено после времени (путем проверки nodeType).

Вот он:

  function getFocus(e){
    var focused;
    if (!e) var e = window.event;
    if (e.target) focused = e.target;
    else if (e.srcElement) focused = e.srcElement;
    if (focused.nodeType == 3) focused = focused.parentNode;
    if (document.querySelector) {
      return focused.id;
    } else if (!focused || focused == document.documentElement) {
      return focused;
    }
  }

Надеюсь, что это поможет.


Благодаря Quirksmode

2
ответ дан 04 июля '17 в 16:57
источник

Google Chrome (по крайней мере, до 33) имеет раздражающую ошибку с document.activeElement: в документах XHTML document.activeElement есть undefined. Я не тестировал другие браузеры на основе webkit, они также могут быть затронуты.

1
ответ дан 05 дек. '17 в 1:03

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

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

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

0
ответ дан 20 окт. '17 в 14:20
источник

Другие вопросы по меткам или Задайте вопрос