div 默认不可聚焦,需通过 tabindex 属性(0、-1 或正整数)和 focus() 方法实现;tabindex="-1" 最常用,focus() 需在 dom 挂载且元素可见时调用,并配合 :focus-visible 样式与 role/aria 属性保障无障碍。

div 默认不能获取焦点,input、button、带 href 的 a 这类可交互元素才天然支持。想让其他元素(比如 div)获得焦点,必须显式赋予它“可聚焦能力”——核心就两条路:tabindex 属性 + focus() 方法。
tabindex 是什么,取哪些值才有效
tabindex 不是“让元素能被点击”,而是告诉浏览器:“这个元素参与键盘导航流程”。它的值决定参与方式:
-
tabindex="0":按 DOM 顺序加入 Tab 键流,用户按 Tab 就能轮到它;适合需要默认可键盘操作的容器(如卡片、菜单项) -
tabindex="-1":不进 Tab 流,但可通过element.focus()手动聚焦;这是最常用、最安全的选择,比如弹窗关闭后把焦点收回到触发按钮 -
tabindex="正整数"(如1、2):强制插入 Tab 流,数值越小越靠前;但极易打乱逻辑顺序,无障碍体验差,除非表单有极特殊导航需求,否则别用
⚠️ 注意:tabindex 必须写在元素上,且该元素不能有 disabled 属性(div 没这个属性,但自定义组件里可能封装了禁用逻辑)。
focus() 方法调用时机很关键
直接写 element.focus() 很容易报错或无效,常见原因不是代码写错,而是时机不对:
- DOM 还没挂载:比如在 Vue 的
data里就调用,或 React 的render函数里执行 —— 此时element是null - 元素不可见:
display: none、visibility: hidden或父级被隐藏时,focus()会静默失败 - 移动端软键盘限制:Safari 和部分安卓 WebView 要求
focus()必须由用户手势(如click、touchend)触发,否则只聚焦不弹键盘
稳妥做法是监听 DOMContentLoaded,或在框架的挂载钩子(如 Vue 的 mounted、React 的 useEffect)里检查 element.offsetParent !== null 再调用。
autofocus 属性只对表单控件生效
autofocus 是个 HTML 属性,但它只对原生可聚焦元素有效:input、textarea、select、button。给 div 加 autofocus 完全没用。
即使对表单元素,它也有硬约束:
- 一个页面只能有一个
autofocus,多写也只生效第一个 - 如果元素被 JS 动态插入(比如模态框内容),
autofocus不会自动触发,得手动focus() - 某些浏览器(尤其是 iOS Safari)在页面加载时不会因
autofocus弹出软键盘,这是策略限制,无法绕过
focus 样式和无障碍必须配套做
加了 tabindex 或调了 focus(),不代表用户就知道焦点在哪。没有视觉反馈,键盘用户根本不知道当前操作的是哪个 div。
必须配 CSS:
div[tabindex] {
outline: 2px solid #007bff;
outline-offset: 2px;
}
更推荐用 :focus-visible 避免鼠标用户的干扰:
div[tabindex]:focus-visible {
outline: 2px solid #007bff;
}
另外,若该 div 承担按钮语义(比如可点击的菜单项),记得加上 role="button" 和 aria-label,否则屏幕阅读器不会把它当可交互元素读出来。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











