preventDefault(),滚动和可访问性

时间:2010-11-08 17:14:37

标签: javascript html cursor accessibility caret

我正在为网站添加一个基于JavaScript的子窗口。基本上,UI的一部分位于屏幕的左边缘,直到用户触发链接;然后它移动到一个可见的位置。我有一系列的五个test cases,但尚未获得单独链接它们的声誉点。

出于辅助目的,我想使用包含文档片段的链接,因此:

<a href="#quicklinks" id="quicklinks-trigger">Quick Links</a>

使用相应的JavaScript(使用jQuery):

$("#quicklinks-trigger").click(function(e){ 
 $("#shadow").removeClass("default");
 $("#shadow").addClass("active");
});

#quicklinks HREF将屏幕阅读器的内部光标(也称为插入符号)重定向到新显示的UI的开头。快速链接子窗口中有相应的链接,它将光标重定向回文档的主要部分(<a href="#main" id="close-quicklinks"></a>)。您可以通过测试用例1看到这一点。如果您使用屏幕阅读器(我正在使用NVDA进行测试),屏幕阅读器会在触发链接时快速跳至快速链接,并返回主文档何时触发快速链接关闭链接。

它还会向上和向下滚动页面以响应文档片段,这是丑陋和烦人的。这可以使用window.preventDefault()来抑制 - 请参阅测试用例2,它非常流畅,不会在文档中滚动,因此:

$("#quicklinks-trigger").click(function(e){ 
 $("#shadow").removeClass("default");
 $("#shadow").addClass("active");

e.preventDefault();     });

不幸的是,对preventDefault()的调用也会阻止浏览器将光标移动到正确的位置。盲人用户可以在那里触发链接,然后屏幕阅读器将按照源代码顺序进入下一个项目,而不是快速链接UI。解决这个问题的最简单方法是在触发链接之后立即放置定义快速链接子窗口的HTML;但是我不能这样做,因为这个目的地的CMS不适合插入菜单中的大块HTML。

我已经尝试了一些其他方法来消除滚动。测试用例3手动滚动窗口:

$("#quicklinks-trigger").click(function(e){ 
 $("#shadow").removeClass("default");
 $("#shadow").addClass("active");
 window.setTimeout(function(){ scrollTo(0,0); }, 1); 
});

...虽然有效但有明显的生涩效果,因为它向下滚动然后再向上,所以这并不比测试用例1好。

在测试用例4中,我尝试将preventDefault()与focus()结合使用,希望手动移动内部游标:

$("#quicklinks-trigger").click(function(e){ 
 $("#shadow").removeClass("default");
 $("#shadow").addClass("active");
 $("#quicklinks").focus();
 e.preventDefault();
});

但它不起作用,因为#quicklinks是一个DIV,而不是一个可聚焦的元素。我想我可以在快速链接HTML中添加一个隐藏的可聚焦元素,但这将是愚蠢的。

在测试用例5中,我尝试从目标元素中删除ID属性,使用onhashchange事件重写片段标识符,然后恢复ID:

function cfl_hash(fragment){
 // Get the section the fragment refers to.
 var target = $(fragment);

 // Save its current ID.
 var id = target.attr("id");

 // Remove the ID so the browser won't scroll.
 target.attr("id","");

 // Rewrite the hash to the desired fragment, only if onhashchange event supported.
 if("onhashchange" in window){ location.hash = fragment; }

 // Put the ID back in place.
 target.attr("id", id);
}

$("#quicklinks-trigger").click(function(e){ 
 $("#shadow").removeClass("default");
 $("#shadow").addClass("active");
 cfl_hash("#quicklinks");
});

允许滚动但阻止光标移动会产生不愉快的效果。我想我在ID交换中有一系列错误的事件;这应该用于抑制滚动,但我怀疑它是否会允许光标移动。

如果不取消屏幕阅读器用户的光标重定向,就无法取消对有视力用户的滚动,这真令人讨厌。

到目前为止,我只测试了Firefox和NVDA。我不知道这将如何在浏览器和屏幕阅读器的其他组合中发挥作用。

建议?

1 个答案:

答案 0 :(得分:1)

我想出了一个解决方法,允许使用文档片段链接,允许插入符号重定向到屏幕阅读器,并且不滚动视口。方法是

  1. 将隐藏元素放置在要链接到的元素的顶部
  2. 链接到隐藏元素而不是其后面的内容
  3. 使用固定定位将隐藏元素与视口顶部齐平移动
  4. 通过这种方式,当您单击指向隐藏元素的链接时,浏览器会尝试将屏幕“滚动”到位,但它已经位于视口顶部,因此不会进行实际滚动。发生插入符重定向,因此屏幕阅读器用户可以到达链接指向的位置。

    有几个怪癖。在Opera,Safari和Chrome中,单击以这种方式排列的链接将导致滚动,但仅在用户已向下滚动时。我不确定为什么会这样;也许他们没有更新屏幕左边的固定位置元素的位置?在任何情况下,此问题仅影响一组非常具体的情况,这些情况通常可以通过合理的页面布局来避免。所以我认为好处(可访问的,相对简单的代码)超过了缺点(在某些浏览器和环境中有轻微的视觉怪癖)。

    有关此技术的更完整讨论,请参阅:

    http://www.accessifyforum.com/viewtopic.php?p=77132

    希望这有助于其他人。