javascript - 如何找到具有焦点的DOM元素?

  显示原文与译文双语对照的内容

我想在Javascript中找出当前有焦点的元素。 我一直在浏览 DOM,但还没有找到我需要的东西。 是否有方法这样做,以及如何?

我寻找这个的原因:

我想做的是制作像箭头这样的键,输入一个输入元素的表格。 选项卡现在工作了,但输入和箭头默认不存在。 我已经设置了密钥处理部分,但现在我需要弄清如何在事件处理函数中移动焦点。

时间:

使用 document.activeElement,所有主流浏览器都支持它。

以前,如果你试图找出什么表单域具有焦点,你不能。 要在旧浏览器中模拟检测,请向所有字段添加一个"聚焦"事件处理程序,并在变量中记录last-focused字段。 添加"模糊"处理程序以清除last-focused字段模糊事件的变量。

相关链接:

就像圣殿所说,你找不到当前的焦点元素,至少在browser-independent中。 但是如果你的应用程序只有 IE ( 有些是。。),你可以通过以下方式找到它:


document.activeElement

编辑:看起来 IE 似乎没有任何错误毕竟,这是HTML5的一部分,似乎被最新版本的Chrome,Safari和 Firefox 支持。

如果你可以使用jquery,它现在支持:重点,确保你使用的是版本 1.6 +。

这里语句将获得当前焦点的元素。

 
$("*:focus")

 

来自:如何选择一个元素与jquery关注它

document.activeElement 现在html5工作草案规范的一部分,但是它可能在某些 non-major/mobile/older 浏览器不支持。 你可以回退到 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 测试列表。

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

我在Mootools中使用了一个小 helper:


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()

JQuery支持当前的:focus pseudo-class 。 如果你在JQuery文档中寻找它,请在"选择器"下检查它,它指向 W3C CSS文档 。 我已经用 Chrome,FF和 IE 7 + 测试过了。 注意,为了在 IE 中工作,<DOCTYPE... 必须存在于html页面上。! 下面是一个假设你已经为具有焦点的元素分配了一个标识:


$(":focus").each(function() {
 alert($(this).attr("id") +" has focus!");
});

如果没有聚焦元素,document.activeElement 可能默认为 <body> 元素。 此外,如果某个元素被聚焦,并且浏览器窗口模糊,activeElement 将继续保持焦点元素。

如果这两种行为中的任一种不可取,请考虑CSS-based方法: document.querySelector(':focus')

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

...