如何找出哪个DOM元素具有焦点?

我想找出,在Javascript中,哪些元素目前有重点。 我一直在浏览DOM,但还没有find我所需要的。 有没有办法做到这一点,以及如何?

我在找这个的原因是:

我正在试图制作像箭头一样的键,并通过input元素表进行导航。 选项卡现在工作,但input和箭头不默认它看起来。 我已经设置了关键处理部分,但现在我需要弄清楚如何在事件处理函数中移动焦点。

使用document.activeElement ,它在所有主stream浏览器中都受支持。

以前,如果你正在试图找出哪个表单重点,你不能。 为了模拟旧版浏览器中的检测,请将​​“焦点”事件处理程序添加到所有字段,并将最后聚焦的字段logging在variables中。 添加一个“模糊”处理程序清除最后聚焦的字段模糊事件的variables。

相关链接:

  • activeElement浏览器兼容性
  • jQuery替代document.activeElement

正如JW所说,至less在浏览器无关的方式下,您无法find当前关注的元素。 但是,如果你的应用程序只有IE浏览器(有些是…),你可以通过以下方式find它:

 document.activeElement 

编辑:它看起来像IE并没有一切都错了,这是HTML5草案的一部分,似乎是最新版本的Chrome,Safari和Firefox至less支持。

如果你可以使用jQuery,它现在支持:focus,只要确保你使用的是1.6+。

这个声明会让你获得当前的焦点元素。

 $(":focus") 

来自: 如何select一个重点与jQuery的元素

document.activeElement现在是HTML5工作草案规范的一部分,但在某些非主stream/移动/旧版浏览器中可能尚不支持。 你可以回退到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"); 

另外要注意的是这两种方法之间的性能差异。 用select器查询文档总是比访问activeElement属性慢得多。 看到这个jsperf.comtesting 。

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

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

我喜欢Joel S使用的方法,但我也喜欢document.activeElement的简单性。 我使用jQuery并将两者结合在一起。 不支持document.activeElement旧版浏览器将使用jQuery.data()来存储“hasFocus”的值。 较新的浏览器将使用document.activeElement 。 我假设document.activeElement会有更好的performance。

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

这样,你可以检查元素是否有焦点与el.hasFocus()提供startFocusTracking()已被调用给定的元素。

JQuery确实支持:focus当前的:focus伪类。 如果您正在JQuery文档中查找它,请在“select器”下find指向W3C CSS文档的位置 。 我已经使用Chrome,FF和IE 7+进行了testing。 请注意,要在IE中工作, <!DOCTYPE...必须存在于html页面上。 假设你已经为拥有焦点的元素分配了一个id,这里是一个例子:

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

阅读其他答案,并尝试自己,似乎document.activeElement会给你在大多数浏览器中所需的元素。

如果你有一个浏览器不支持document.activeElement,如果你有jQuery,你应该可以用像这样简单的东西来填充所有焦点事件(未经testing,因为我没有满足这些标准的浏览器) ):

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

如果您使用的是jQuery,那么可以使用它来查明一个元素是否处于活动状态:

 $("input#id").is(":active"); 

使用document.activeElement存在潜在的问题。 考虑:

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

如果用户关注内部d​​iv,则document.activeElement仍然引用外部div。 您不能使用document.activeElement来确定哪个内部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.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; }); 

如果你想得到一个Element实例的对象,你必须使用document.activeElement ,但是如果你想获得一个实例为Text的对象,你必须使用document.getSelection().focusNode

我希望有所帮助。

使用dojo,你可以使用dijit.getFocus()

只是把这个放在这里给我解决scheme,我最终想出了。

我创build了一个名为document.activeInputArea的属性,并使用jQuery的HotKeys插件来捕获箭头键,选项卡和input的键盘事件,并创build了一个用于点击input元素的事件处理程序。

然后我调整了activeInputArea每次焦点改变,所以我可以使用该属性来找出我在哪里。

虽然这很容易搞砸,因为如果你在系统中有一个错误,而重点不在你认为的地方,那么很难恢复正确的焦点。

Quirksmode很早以前就采用了几乎独立于浏览器的方法来实现这一目标。 Safari可能会遇到问题,因为Safari并不总是将事件设置为与Chrome或Firefox相同的元素。 有时Safari甚至会在textnode而不是包含元素上设置事件。 这可以在课程之后纠正(通过检查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

我发现下面的代码片段在试图确定哪个元素当前有焦点时很有用。 将以下内容复制到浏览器的控制台中,并且每秒钟都会打印出当前具有焦点的元素的详细信息。

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

随意修改console.log来注销一些不同的东西,如果打印出整个元素并不能帮助你精确定位元素,可以帮助你找出确切的元素。