使用 keydown 处理程序控制焦点时,焦点轮廓在 Chrome 中不可见

Focus outline is invisible in Chrome when using a keydown handler to control focus

我有一个<input type="text" />

当我从文本字段 Shift+Tab 时,我想关注一个 li > a。在这种情况下,我不能依赖原生的 Tab 键行为,因为我在 <input /> 和目标 <a /> 之间有一个我不想关注的锚元素。

因此,我添加了一个 keydown 侦听器,强制将焦点放在我关心的 <a /> 上。

然而,在 Chrome 中,当我从 <input /> 关注 <input />Shift+Tab 时,焦点转到最后一个<a />,但是轮廓是看不见的。如果我再执行一次 Shift+Tab + Tab 返回到 B,我现在可以看到轮廓了。

document.getElementById("f").addEventListener("keydown", (e) => {
  if (e.key === "Tab" && e.shiftKey) {
      e.preventDefault();
      document.querySelector("#list1 > li:last-child > a").focus();
  }
});
<ul id="list1">
  <li><a href="#">A</a></li>
  <li><a href="#">B</a></li>
</ul>

<a href="#" />
<input id="f" />

如果我删除 keydown 处理程序和文本字段与我想要聚焦的目标锚点之间的锚点元素,则焦点轮廓会正确呈现。

这是一个已知的 Chrome 错误吗?是否有任何解决方法? (使用 Chrome 74)

您可以使用 tabindex 属性阻止其他锚点获得焦点。这是一个例子:

<ul id="list1">
  <li><a href="#">A</a></li>
  <li><a href="#">B</a></li>
</ul>

<a href="#" tabindex="-1"/>
<input id="f" />

这可能不适用于所有浏览器。

您可以考虑移除e.preventDefault();,然后等待几毫秒再设置焦点:

document.getElementById("f").addEventListener("keydown", function (e) {
    if (e.key === "Tab" && e.shiftKey) {
        setTimeout(function() {
            document.querySelector("#list1 > li:last-child > a").focus();
        }, 10);
    }
});
<ul id="list1">
    <li><a href="#">A</a></li>
    <li><a href="#">B</a></li>
</ul>

<a href="#" />
<input id="f" />