如何找出获得焦点的DOM元素

如何找出获得焦点的DOM元素

技术背景

在Web开发中,有时需要确定哪个DOM元素当前获得了焦点,比如在表单验证、用户交互跟踪等场景中。然而,不同浏览器对焦点元素的检测支持存在差异,这就需要我们采用不同的方法来实现这一功能。

实现步骤

现代浏览器

在现代浏览器中,可以使用 document.activeElement 来获取当前获得焦点的元素。示例代码如下:

1
2
const focusedElement = document.activeElement;
console.log(focusedElement);

旧浏览器模拟检测

对于旧浏览器,可以通过添加 focusblur 事件处理程序来模拟检测。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
let lastFocusedField = null;
const fields = document.querySelectorAll('input, textarea, select');
fields.forEach(field => {
field.addEventListener('focus', () => {
lastFocusedField = field;
});
field.addEventListener('blur', () => {
if (lastFocusedField === field) {
lastFocusedField = null;
}
});
});

使用jQuery

如果使用jQuery,可以使用 :focus 伪类来获取当前获得焦点的元素。示例代码如下:

1
2
const $focusedElement = $(':focus');
console.log($focusedElement);

处理 contentEditable 元素

对于 contentEditable 元素,document.activeElement 可能返回外层元素,此时可以使用 window.getSelection().anchorNode 来获取实际获得焦点的节点。示例代码如下:

1
2
3
4
5
function active_node() {
return window.getSelection().anchorNode;
}
const focusedNode = active_node();
console.log(focusedNode);

检查特定元素是否获得焦点

可以使用 document.activeElement 结合 document.hasFocus() 来检查特定元素是否获得焦点。示例代码如下:

1
2
3
const input = document.getElementById('myInput');
const input_focused = document.activeElement === input && document.hasFocus();
console.log(input_focused);

检查是否有元素获得焦点

可以使用 document.hasFocus() 结合 document.activeElement 来检查是否有元素获得焦点。示例代码如下:

1
2
3
4
5
6
7
const anything_is_focused = (
document.hasFocus() &&
document.activeElement !== null &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
);
console.log(anything_is_focused);

核心代码

以下是一个综合的示例代码,展示了如何使用不同方法获取当前获得焦点的元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 现代浏览器使用 document.activeElement
const focusedElementModern = document.activeElement;
console.log('现代浏览器使用 document.activeElement:', focusedElementModern);

// 旧浏览器模拟检测
let lastFocusedField = null;
const fields = document.querySelectorAll('input, textarea, select');
fields.forEach(field => {
field.addEventListener('focus', () => {
lastFocusedField = field;
});
field.addEventListener('blur', () => {
if (lastFocusedField === field) {
lastFocusedField = null;
}
});
});
console.log('旧浏览器模拟检测:', lastFocusedField);

// 使用jQuery
const $focusedElement = $(':focus');
console.log('使用jQuery:', $focusedElement);

// 处理 contentEditable 元素
function active_node() {
return window.getSelection().anchorNode;
}
const focusedNode = active_node();
console.log('处理 contentEditable 元素:', focusedNode);

// 检查特定元素是否获得焦点
const input = document.getElementById('myInput');
const input_focused = document.activeElement === input && document.hasFocus();
console.log('检查特定元素是否获得焦点:', input_focused);

// 检查是否有元素获得焦点
const anything_is_focused = (
document.hasFocus() &&
document.activeElement !== null &&
document.activeElement !== document.body &&
document.activeElement !== document.documentElement
);
console.log('检查是否有元素获得焦点:', anything_is_focused);

最佳实践

  • 优先使用 document.activeElement:在现代浏览器中,document.activeElement 是获取当前获得焦点元素的最佳方法,因为它的性能较好。
  • 考虑浏览器兼容性:对于旧浏览器,需要使用事件处理程序来模拟检测。
  • 结合 document.hasFocus():在检查特定元素是否获得焦点或是否有元素获得焦点时,结合 document.hasFocus() 可以避免在浏览器窗口失去焦点时产生误判。

常见问题

  • document.activeElement 返回 body:如果没有可聚焦的元素获得焦点,document.activeElement 可能会返回 body 元素。可以结合 document.hasFocus() 来判断是否真的有元素获得焦点。
  • contentEditable 元素问题:对于 contentEditable 元素,document.activeElement 可能返回外层元素,此时需要使用 window.getSelection().anchorNode 来获取实际获得焦点的节点。
  • 浏览器兼容性问题:不同浏览器对 document.activeElement:focus 伪类的支持可能存在差异,需要进行兼容性测试。

如何找出获得焦点的DOM元素
https://119291.xyz/posts/how-to-find-focused-dom-element/
作者
ww
发布于
2025年5月28日
许可协议