如何找出获得焦点的DOM元素
技术背景
在Web开发中,有时需要确定哪个DOM元素当前获得了焦点,比如在表单验证、用户交互跟踪等场景中。然而,不同浏览器对焦点元素的检测支持存在差异,这就需要我们采用不同的方法来实现这一功能。
实现步骤
现代浏览器
在现代浏览器中,可以使用 document.activeElement
来获取当前获得焦点的元素。示例代码如下:
1 2
| const focusedElement = document.activeElement; console.log(focusedElement);
|
旧浏览器模拟检测
对于旧浏览器,可以通过添加 focus
和 blur
事件处理程序来模拟检测。示例代码如下:
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
| 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);
const $focusedElement = $(':focus'); console.log('使用jQuery:', $focusedElement);
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
伪类的支持可能存在差异,需要进行兼容性测试。