将初始选项卡设置为新创建的元素而不会弄乱屏幕阅读器

时间:2017-01-07 07:31:22

标签: javascript html accessibility screen-readers tabindex

将新的html插入某个部分时,我希望第一个标签按下以跳过前几个链接,并专注于以后的链接。目前,我的解决方案是在<span>处插入空tabindex='-1',然后在其上调用focus()。但是,我注意到屏幕阅读软件会跳转到focus()。是否有另一种方法来设置初始标签焦点,或使屏幕阅读软件忽略focus()? (对于NVDA,我插入的div是一个role='status',每当它更新时都应该被读取,并且focus()在大约40%的时间内抓住NVDA,没有任何看似图案。)

失败的方法是tabindex。对于插入元素的第一个标签按下,Firefox和Chrome都不尊重tabindex。在下面的代码示例中,第二个元素具有最后一个tabindex,但在Firefox中首先关注。 Firefox中的行为在第一个标签按下和后续标签按下之间有所不同。 Chrome会首先忽略第一个标签焦点的tabindex,因此第一个标签焦点始终是第一个链接。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
	<script>
	function k() {
    	document.getElementById("h").innerHTML = "<button tabindex='2' onclick='k()'>first</button><button tabindex='3' onclick='k()'>second</button><button tabindex='1' onclick='k()'>third</button>";
    }
    </script>
<div id="h"><button onclick='k()'>click me</button></div>
</body>
</html>

我还尝试使用<span>标记空aria-hidden='true',但这没有帮助。

1 个答案:

答案 0 :(得分:0)

尝试1:从测试开始,如果拥有现有焦点的DOM元素被销毁,则接收标签焦点的下一个对象不稳定,并且在Firefox和Chrome上表现不同。

在Firefox上,焦点是&#34;幽灵转移&#34;到第一个要显示的文本顺序元素,然后第一个选项卡将从第一个元素向前和向后移动。因此,选项卡将到达其Tab键顺序位于第一个元素之后的元素,并且shift选项卡将到达其Tab键顺序位于第一个元素之前的元素。

在Chrome上,第一个标签的焦点将出现在第一个文字顺序元素上,无论tabindex是什么。

这意味着如果DOM元素被破坏,tabindex是一个非工作的解决方案。

尝试2:替代方案是focus()。使用tabindex =&#39; -1&#39;插入ghost元素style =&#39; outline:none&#39;,然后在其上调用focus(),确实将tab设置为我希望它关注的元素。然而,这具有拧紧屏幕阅读器的问题。每当调用focus()时,屏幕阅读器(经过NVDA测试)可能会执行以下三种操作之一:

  1. 阅读我想要的新消息文本(20%偶然)
  2. 阅读Window标题,然后选项卡标题,然后是focus()d元素,这是可怕的(70%几率)
  3. 什么都不读(10%偶然)
  4. 咏叹调隐藏没有帮助。自动对焦什么都不做。

    尝试3:这意味着focus()不是一个可接受的解决方案。所以唯一的选择是不破坏DOM元素。因此必须移动DOM元素。 然而,如果我们不断推动那里的东西,移动元素的墓地将会填满。如果它包含我们的焦点元素,我们就无法删除墓地元素,否则我们将处于被破坏的焦点元素状态。在我的情况下,互动小说将在几个小时内将这个墓地填满数千兆字节。 因此,在删除历史记录日志元素时,我们必须检查元素及其所有子元素,以确保焦点不包含在那里,然后如果它一直在它周围跳舞。

    尝试4:然而,事实证明移动元素无论如何都会杀死它的焦点(至少在Firefox上)。所以你不能把它移到坟墓场,你根本不要碰它。

    一旦你有一个幸存的物体,你还没有移动到任何地方,你需要设置tabindex =&#39; -1&#39;在它上面,否则这个墓地对象会搞乱你的Tab键顺序。但是,如果您将其tabindex设置为-1,那么(至少在Firefox上),Tab键顺序现在再次表现为destroy-DOM-object情况。

    尝试5:

    1. 不要把那个消失的物体移到任何地方!
    2. 取而代之,取出该对象,然后隐藏它。
    3. 围绕它构建新对象:旧对象必须按文本顺序准确放置在您希望制表位置的位置。你的新内容将在它之前的一半和之后的一半。
    4. 检查activeElement的所有隐藏对象的子节点(递归地)以找出其焦点位置。对于不是具有焦点的节点的父节点的每个非活动元素,您必须删除它,否则屏幕阅读器会抱怨很多。对于幸存的节点,确保它们完全不可见且没有内容,但不要使用display:none,这会破坏焦点。在焦点节点上设置tabindex = -1。
    5. 如果你的焦点不在你删除的对象中,那么找到拥有焦点的对象,并将其tabindex设置在上半部分和下半部分的tabindex之间。
    6. 我已经没有耐心了,我不打算实施这个提议的解决方案,在新文本的中间留下神秘的半删除,半隐藏元素。经过5次尝试失败之后,我没有太多的希望,而且我不想让维护者留下深度评论页面,奇怪的不直观行为和意想不到的性能问题,仅针对屏幕阅读器。我将坚持使用旧的focus()解决方案。