最稳妥方案是监听 table 的 mouseover 事件,用 event.target.closest('td') 获取目标单元格;title 属性无法满足焦点提示的可访问性与样式需求,应改用动态添加 class、设置 tabindex="-1" 并调用 focus() 实现;需配合 mouseleave 清除焦点,并通过键盘方向键维护 currentcell 确保鼠标与键盘导航高亮一致。

鼠标移入时如何准确获取目标 <td> 元素
<p>直接监听 <code>table 的 mouseover 事件最稳妥,避免为每个 <td> 单独绑定事件导致性能浪费或动态添加单元格时失效。关键是要用 <code>event.target 并向上查找最近的 <td>,因为鼠标可能落在子元素(如文字、<code><span></span>)上,而非 <td> 本身。
<p>常见错误是直接判断 <code>event.target.tagName === 'TD',结果在单元格内有嵌套标签时漏匹配。正确做法:
table.addEventListener('mouseover', (e) => {
const td = e.target.closest('td');
if (!td) return;
// 此时 td 就是真正被鼠标进入的单元格
});
为什么不能用 title 属性实现焦点提示
title 属性实现焦点提示title 是浏览器原生提示,无法控制样式、位置、延迟或触发时机,且在移动端基本不可靠;更重要的是,它和“焦点”语义无关——title 不响应键盘导航,也不与 tabindex 或 focus 状态联动,纯属 tooltip 替代方案,违背“焦点提示”的交互意图。
真正需要的是视觉反馈 + 可访问性支持,所以必须:
- 给目标
<td> 动态添加 class(如 <code>focused-cell),配合 CSS 高亮 - 同时设置
tabindex="-1",使该单元格可被脚本聚焦(但不进入自然 tab 顺序) - 调用
td.focus()触发focus事件,让屏幕阅读器感知
focus 和 blur 事件在 <td> 上的行为差异
<p><code><td> 默认不可聚焦,即使加了 <code>tabindex,它的 focus 事件也不会像 <input> 那样自动触发浏览器默认焦点环——需手动用 CSS 定义 :focus 样式,否则用户看不到任何变化。
另一个易忽略点:鼠标移出时不能只靠 mouseout 清除焦点,因为 mouseout 在子元素间移动也会触发,造成闪烁。应改用 mouseleave 监听 table,并确保只在真正离开表格区域时才 blur():
table.addEventListener('mouseleave', () => {
const focused = document.querySelector('td.focused-cell');
if (focused) {
focused.classList.remove('focused-cell');
focused.blur(); // 移除焦点状态
}
});
键盘导航下如何保持焦点提示一致
仅靠鼠标逻辑不够。用户按 Tab 进入表格后,用方向键移动时,<td> 不会自动获得焦点——必须显式捕获键盘事件,模拟“当前活动单元格”概念。
<p>建议维护一个 <code>currentCell 变量,结合 keydown 处理方向键(ArrowUp/ArrowDown/ArrowLeft/ArrowRight),计算行列索引并聚焦对应 <td>。注意两点:
<ul><li>首次 Tab 进入表格时,应自动聚焦第一个 <code><td>(或带 <code>data-start="true" 的单元格)
blur() 上一个,再 focus() 新的,并同步更新 focused-cell class否则鼠标悬停高亮和键盘导航高亮会错位,破坏一致性。
真实场景里,单元格是否可聚焦、是否跳过空单元格、是否循环滚动,都得按业务逻辑细调——这些边界情况比事件绑定本身更耗调试时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











