document.activeelement 返回当前获得焦点的 dom 元素,仅在页面加载后有聚焦元素、用户点击/tab 切换或调用 focus() 时返回有效节点;默认为 body 或 html,需类型检查与 focusin/focusout 事件配合使用。

document.activeElement 是一个只读属性,返回当前页面中获得焦点的 DOM 元素(即用户正在交互、或通过 Tab 键、JavaScript 聚焦的元素)。它不用于“查询”任意元素,而是实时反映焦点状态,常用于表单验证、键盘导航、无障碍支持等场景。
什么时候能获取到有效元素?
只有在以下情况下,document.activeElement 才返回有意义的 DOM 节点:
- 页面加载后,某个
<input>、<textarea></textarea>、<button></button>、带tabindex的元素已获得焦点; - 用户点击了可聚焦元素,或按 Tab / Shift+Tab 切换焦点;
- 代码中主动调用了
element.focus(); - 注意:页面刚加载未触发任何聚焦行为时,通常返回
或(取决于浏览器)。
基础用法与判断技巧
直接访问即可,但建议加类型检查避免误用:
const focused = document.activeElement;
if (focused && focused.tagName === 'INPUT') {
console.log('当前聚焦的是输入框,类型为:', focused.type);
}
// 或更稳妥地判断是否为表单控件
if (focused.matches('input, textarea, select, button, [contenteditable]')) {
console.log('聚焦在可编辑/可交互元素上');
}
配合事件监听实现动态响应
单纯读取一次不够,多数需求需监听焦点变化。推荐使用 focusin 和 focusout 事件(它们冒泡,比 focus/focusout 更易捕获):
document.addEventListener('focusin', (e) => {
console.log('获得焦点的元素:', e.target);
console.log('当前 activeElement:', document.activeElement); // 通常与 e.target 一致
});
document.addEventListener('focusout', (e) => {
console.log('失去焦点的元素:', e.target);
});
常见注意事项
注意以下易错点:
-
iframe 内容不受影响:如果焦点在 iframe 中的元素上,
document.activeElement返回的是该 iframe 元素本身,不是其内部元素(需访问iframe.contentDocument.activeElement); -
Shadow DOM 中需穿透:若聚焦元素位于 Shadow Root 内,
document.activeElement仍能正确返回,但需确保 Shadow Root 是 open 模式; -
异步时机问题:在
setTimeout(() => console.log(document.activeElement), 0)中读取,有时比同步读取更可靠(尤其在某些 UI 框架更新后); -
不可聚焦元素不会被返回:比如普通
<div> 默认无焦点,除非设置了 <code>tabindex="-1"或tabindex="0"。











