拦截最后一个可聚焦元素上的"模糊"事件



我正在开发一个模式组件,用于我所在组织的网站和数字服务(在过去15多年中创建了约17000个页面,每月拥有数百万用户)。正如你所能想象的,这些页面差异很大,不可能全部测试。

为了最大限度地提高该组件的可访问性,我需要在模态打开时将焦点(通过tab键和/或虚拟光标)限制在模态上

我的方法是在最后一个可聚焦元素上的blur事件上附加一个处理程序,该处理程序将焦点返回到模态中的第一个可聚焦的元素。这样做非常好,除非模态中的最后一个可聚焦元素也是页面上的最后一次可聚焦元素,在这种情况下,焦点会返回到浏览器搜索栏。

几天来,我一直对此感到困惑,无法找到任何信息来说明为什么会出现这种情况

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Focus trap</title>
<style>button:focus {background-color: orange;}</style>
</head>
<body>
<div id="modal">
<button id="link-1">Link-1</button>
<button id="link-2">Link-2</button>
<button id="link-3">Link-3</button>
</div>
<script>
let last_link = document.getElementById('link-3'),
first_link = document.getElementById('link-1');
last_link.addEventListener('blur', () => {
first_link.focus();
})
</script>
</body>
</html>

我知道我们可以做一些事情,但这些都不理想:

  • 尝试拦截键盘事件而不是blur,但我不愿意这样做,因为这可能会排除某些辅助技术的用户
  • 在模态中创建并隐藏一个额外的可聚焦元素——我不愿意这样做,因为这感觉有点像黑客

您不能反对地址栏或本机工具栏被聚焦。他们优先于你能说的任何话,幸运的是,有很好的理由这样做

解决方案是您已经提到的两个选项之一:

  • 截取最后一个元素的tab,以及第一个元素的shift+tab
  • 放置两个隐藏的可聚焦元素,一个在开头,一个放在结尾,一旦隐藏的可对焦元素获得焦点,就将焦点移动到第一个或最后一个元素

我看不出哪种辅助技术会被tab/shift+tab拦截击败。如果你考虑触摸界面,无论如何,iOS/Android的工作方式完全不同。如果你考虑一下特殊的设备,它们中的许多都会模拟按下键盘上的键,而与触发它们动作的有效方式无关。

如果有疑问,第二个看起来更像是黑客攻击,但如果有一种有效的特殊方式来移动焦点,而不是通过键盘,则会更强大。

最新更新