我想知道在JavaScript中,哪个元素当前具有焦点。我一直在浏览DOM,还没有找到我需要的东西。有没有办法做到这一点,以及如何做到?

我找这个的原因是:

我正在尝试制作像箭头一样的键,并输入在输入元素表中导航。Tab键现在起作用了,但输入和箭头在默认情况下似乎不起作用。我已经设置了关键处理部分,但现在我需要弄清楚如何将焦点转移到事件处理功能上。


当前回答

阅读其他答案,并尝试自己,看起来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
  });
}

其他回答

使用document.activeElement可能存在问题。请考虑:

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

如果用户关注内部div,那么document.activeElement仍然引用外部div。您不能使用document.active Element来确定哪个内部div具有焦点。

以下函数绕过此问题,并返回聚焦节点:

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;
  }
}

把这个放在这里是为了给出我最终想出的解决方案。

我创建了一个名为document.activeInputArea的属性,并使用jQuery的热键插件来捕获箭头键、tab和enter的键盘事件,我还创建了用于单击输入元素的事件处理程序。

然后,每次焦点改变时,我都会调整activeInputArea,这样我就可以使用该属性来查找我所在的位置。

不过,这很容易搞砸,因为如果你的系统中有一个bug,并且焦点不在你认为的位置,那么很难恢复正确的焦点。

如果您想在开发工具上测试重点元素,我建议使用。

$(":focus")

当您单击开发工具中的任何内容时,As document.activeElement将变为body。

我喜欢Joel S使用的方法,但我也喜欢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);

使用document.activeElement.id

appending.id过滤掉返回的整个DOM,并允许您仅处理已标识的元素