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

IT技术 javascript dom
2021-01-17 17:34:36

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

我正在寻找这个的原因:

我正在尝试制作箭头之类的键并enter在输入元素表中导航。Tab 现在可以工作,但输入和箭头似乎默认情况下不起作用。我已经设置了关键处理部分,但现在我需要弄清楚如何在事件处理函数中移动焦点。

6个回答

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

以前,如果您试图找出哪个表单字段具有焦点,则无法找到。要在旧浏览器中模拟检测,请向所有字段添加“焦点”事件处理程序,并将最后一个焦点字段记录在变量中。添加“模糊”处理程序以在最后聚焦的字段的模糊事件时清除变量。

如果您需要删除activeElement您可以使用模糊;document.activeElement.blur(). 它将更改activeElementbody

相关链接:

不确定它是否有帮助,但是您可以通过包含属性 tabindex="0" 使 div 等元素接收键盘焦点
2021-03-11 17:34:36
不确定 IE,但 FF 和 Safari 都返回 BODY 元素。
2021-03-12 17:34:36
@Rudie,@Stewart:我已经在你的小提琴上建立了一个更精致的游乐场:jsfiddle.net/mklement/72rTF您会发现唯一可以真正聚焦这样的主要浏览器(截至 2012 年末)div是 Firefox 17,并且只能通过Tab 键切换到它。所有主要浏览器返回的元素类型document.activeElement仅限于与输入相关的元素。如果没有这样的元素具有焦点,则所有主要浏览器都会返回该body元素 - 除了 IE 9,它返回该html元素。
2021-03-20 17:34:36
任何访问document.activeElement都应包含在 a 中,try catch因为在某些情况下它可能会引发异常(不仅仅是 IE9 AFAIK)。请参阅bugs.jquery.com/ticket/13393bugs.jqueryui.com/ticket/8443
2021-03-21 17:34:36
activeElement实际上不返回焦点元素。任何元素都可以有焦点。如果文档有 4 个 'scrolldivs',则这些 div 中的 0 个或 1 个可通过箭头键滚动。如果您单击一个,该 div 将被聚焦。如果在所有外部单击,则主体会聚焦。你如何找出哪个 scrolldiv 被关注?jsfiddle.net/rudiedirkx/bC5ke/show(检查控制台)
2021-03-31 17:34:36

正如 JW 所说,您无法找到当前聚焦的元素,至少以独立于浏览器的方式。但是如果您的应用程序仅适用于 IE(有些是...),您可以通过以下方式找到它:

document.activeElement

看来 IE 毕竟并没有什么问题,这是 HTML5 草案的一部分,似乎至少得到了最新版本的 Chrome、Safari 和 Firefox 的支持。

它为大多数元素返回“body”。几乎没用。
2021-03-15 17:34:36
FF3也是。这实际上是围绕“焦点管理”的 HTML5 规范的一部分。
2021-03-22 17:34:36
它适用于当前版本的 Chrome 和 Opera (9.62)。不适用于 OS X 上的 Safari 3.2.3,但它适用于昨天发布的 Safari 4 :)
2021-03-25 17:34:36
当您使用键盘在元素上使用 Tab 键时,它仅适用于 chrome (20) / safari (5.1.3)。如果您单击它,则 jquery :focus 选择器和 document.activeElement 都不会成功返回您单击的内容(分别返回 undefined 和 document body 元素)。PS 我不敢相信这个线程已经有 2 年的历史了,而且 webkit 上仍然存在回归问题,还有跳过链接不起作用的问题,但是添加实验性 css3 已经做了很多工作。想我可能会回去向我的家人和朋友推荐firefox。
2021-03-31 17:34:36
chrome 19 仍然相同:S
2021-04-01 17:34:36

如果您可以使用 jQuery,它现在支持 :focus,只需确保您使用的是 1.6+ 版本。

此语句将为您提供当前关注的元素。

$(":focus")

来自:如何使用 jQuery 选择具有焦点的元素

这很好,但是 jQuery 是如何做到的呢?文档.activeElement?我找到了这个: return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2021-04-03 17:34:36

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 测试

document.activeElement如果文档没有聚焦(因此文档中的任何内容都没有聚焦!),它本身仍然可以返回一个元素

可能想要这种行为,或者它可能无关紧要(例如在一个keydown事件中),但是如果您需要知道某些事情实际上是集中的,您可以另外检查document.hasFocus().

如果有,以下将为您提供焦点元素,否则为null

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

要检查是否有任何重点,它再次变得更加复杂:

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

健壮性说明:在检查document.body的代码中document.documentElement,这是因为某些浏览器会返回其中之一,或者null当没有任何焦点时。

它不考虑<body>(或可能<html>)是否具有tabIndex属性,因此实际上可以被 focus如果您正在编写一个库或其他东西并希望它健壮,您可能应该以某种方式处理它。


是获取焦点元素的(引用)“单行”版本,它在概念上更复杂,因为您必须了解短路,并且您知道,它显然不适合在一条线上,假设您希望它是可读的。
我不会推荐这个。但是,如果您是 1337 hax0r,idk...它就在那里。如果您不介意在某些情况下获得
您也可以移除该|| null部件falsenull如果document.activeElement是,你仍然可以得到null):

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

您可以通过使用非事件方式来修复初始状态假设,但您也可以使用它来代替。