Tab键导航时焦点顺序乱了怎么办?
我做了一个模态弹窗,里面有几个按钮和输入框,但按Tab键时焦点顺序完全不对,有时候直接跳到浏览器地址栏去了。明明元素都在页面上,而且都设置了tabindex,怎么还是不按顺序走?
我试过把tabindex设成1、2、3,也试过用0让它们按自然顺序,但都不行。是不是哪里漏了?下面是我给弹窗加的代码:
document.addEventListener('keydown', (e) => {
if (e.key === 'Tab' && modalOpen) {
const focusable = modal.querySelectorAll('button, input, [tabindex]');
const first = focusable[0];
const last = focusable[focusable.length - 1];
if (e.shiftKey && document.activeElement === first) {
last.focus();
e.preventDefault();
} else if (!e.shiftKey && document.activeElement === last) {
first.focus();
e.preventDefault();
}
}
});
首先,你的代码逻辑大致是对的,但在处理焦点顺序上还需要做一些调整。我注意到你只关注了第一个和最后一个可聚焦元素,但中间的元素顺序可能存在问题。此外,设置 tabindex 也需要特别注意。
这里有个改进后的方案:
这个代码做了几个重要的改进:
1. 使用 Array.from 和 filter 确保我们只处理有效的可聚焦元素
2. 对元素进行排序,确保 tabindex 的顺序正确
3. 增加了防止焦点跳出模态框的检查
需要注意的是,设置 tabindex 时要特别小心。如果给元素设置非零值,必须保证它们是连续且合理的。比如如果你有三个按钮,分别设置为 1、2、3 是可以的,但如果设置成 1、3、2 就会造成顺序混乱。
另外一个小建议是在关闭模态框时,记得重置 tabindex 或者移除相关事件监听器,否则可能会造成内存泄漏或者影响其他组件的行为。开发这些东西真是容易让人抓狂啊,不过慢慢调试总能搞定的。