Ajax和Screenreader:什么时候可以工作?

在过去的几个月中,我们所有人都听到了很多有关AJAX的嗡嗡声,在这次演讲中,出现了许多文章,技巧,演示文稿和实用API,旨在探索各种可能性并尝试获得最佳实践技术。 但是,尽管有很多激动和炒作,但关于AJAX和可访问性的话题却很少。

Google确实产生了一些结果,特别是在standard-schmandards上的文章“ AJAX和可访问性” ,其中谈到了确保应用程序在不使用JavaScript的情况下工作,还提出了使用警报对话框将信息传递给屏幕阅读器的想法。 但是从文章的语气中可以清楚地看出,作者只是猜测这种方法会起作用(我们将在后面看到,可能不会)。 西蒙·威利森(Simon Willison)在SitePoint博客中讨论了该主题,但他仅在JavaScript支持方面谈论可访问性。

支持JavaScript的设备会出现更复杂,更细微的问题,但仍可能无法与您的应用程序进行交互。 基于浏览器的屏幕阅读器是这样的:它们是具有脚本功能的浏览器,但是其实际的JavaScript支持与单独的浏览器完全不同。

WebAIM上的文章“ AJAX应用程序的可访问性(第1部分)”解决了这一点,并解释说,如果要访问动态接口更改,则应用程序必须主动通知用户已发生更改,然后允许直接访问新内容。 就本文而言,这是可能的-到目前为止,它还没有任何关于如何实际完成操作的内容。 它充满信心地承诺在第2部分中提供解决方案,但是承诺很容易!

无论在哪里浏览 ,无论是在AccessifyForum上的讨论,还是Derek FeatherstonePeter Paul-Koch之类的流行博客中,我们都可以同意的一件事是,我们需要更多信息。

这就是为什么我写这篇文章:展示一些我编译过的数据和分析,看看它是否指向一个有用的结论。

一点背景…

在过去的几个月中(以及更早的时候),我一直在研究领先的屏幕阅读器和其他辅助设备如何响应JavaScript:它们会生成或响应哪种事件,以及在什么情况下。 该研究基于Access Matters ,由Bob Easton,Derek Featherstone,Mike Stenhouse和我本人进行协调。

除此之外,我还为最近出版的《 JavaScript Anthology》做了大量基础研究。 该研究的目的是找出辅助设备如何响应周期性或异步更新DOM的脚本,例如滚动的新闻自动收录器中的项目或对XMLHttpRequest的响应。

我们发现,屏幕阅读器中的脚本支持异常不稳定且支离破碎-但这甚至不是最大的问题! 我们可以通过多种方式来创建可用的挂钩(例如,我们测试的所有屏幕阅读器都会在链接和表单控件上生成点击事件),但真正的症结在于:屏幕阅读器用户如何知道内容已经改变?

有视力的用户可以随机访问页面,因为他或她可以查看页面的不同部分。 如果发生变化,我们可以在视觉上吸引用户的注意。 但是盲人没有这种机会。 他们对页面的处理方式是线性的,因此,如果该页面的一部分在当前焦点的位置之前或之后发生更改,则用户将不会注意到这种情况的发生,并且即使随后遇到这种情况,也可能不会意识到它的发生。

屏幕阅读器不会宣布对DOM的动态更改-这些更改仅在后台发生-因此,除非我们以某种方式通知用户,否则任何给定的更改很可能不会被注意到。

这就是6​​4,000美元的问题:我们该怎么做? 要回答该问题,我们需要尝试一些不同的策略,然后查看(或更确切地说,听听)结果!

测试

在开始之前,您可能想要下载所有这些测试的存档 ,因此您可以参考它们或自己运行测试。

第一次测试

第一个测试只是在trigger元素下面直接更新一段文本。 这是核心HTML:

<p> 
   <a href="./" id="trigger">This link is the trigger.</a>
</p>

<p id="response">
   This paragraph will update with the response.
</p>

<p>
   This is some text that comes after the response,
   to check continuity.
</p>

这是JavaScript:

window.onload = function() 
{
 var trigger = document.getElementById('trigger');
 var response = document.getElementById('response');

 trigger.onclick = function()
 {
   var request = null;
   if(typeof window.XMLHttpRequest != 'undefined')
   {
     request = new XMLHttpRequest();
   }
   else if(typeof window.ActiveXObject != 'undefined')
   {
     try { request = new ActiveXObject('Microsoft.XMLHTTP'); }
     catch(err) { request = null; }
   }

   if(request != null)
   {
     request.onreadystatechange = function()
     {
       if (request.readyState == 4  
           && /^(200|304)$/.test(request.status.toString()))
       {
         response.innerHTML = request.responseText;
       }
     }

     request.open('GET', 'test.php?msg=Hello+World', true);
     request.send(null);
   }

   return false;
 };
};

“ test.php”脚本只为请求的responseText输出一条消息; 可能是什么:

<?php 

echo "And here's the response - " . $_GET['msg'];

?>

为了执行测试,我们使用键盘导航至触发链接,并按Enter键以激活该链接。 预计所有设备都会启动该功能,但是它们随后的响应方式可能会有很大不同。

第一次测试的结果

所有设备都会触发该功能,并且大多数会更新响应段落,但是没有设备会自动读取它(按预期方式)。 该测试仅用于确保内容更新得到普遍认可,但不幸的是,它不是:Windows Eyes不会更新其语音输出,直到触发链接模糊为止,如果我们只是让读者阅读,则不会发生继续阅读。 因此,根据用户的交互,他们可能根本听不到更新的消息。

不过,这并不是一个不好的开始,也许我们的Windows Eyes问题是此示例所独有的。 我们在这里寻找的不仅仅是更新-我们希望有一种方法能够自动说出响应,而无需用户的进一步干预; 让我们继续努力吧。

第二次测试

第二个测试与第一个测试几乎相同,但是这次我们将采取额外的步骤,将document.location设置为响应段落的片段标识符(ID)(使其成为页内目标)。 这是onreadystatechange函数的附加功能(以粗体显示):

request.onreadystatechange = function() 
{
 if (request.readyState == 4
     && /^(200|304)$/.test(request.status.toString()))
 {
   response.innerHTML = request.responseText;
   document.location = '#response';
 }
}

第二次测试的结果

这些结果令人费解:

  • 在Home Page Reader 3.02中,响应文本会自动读出,但阅读器并不会就此停止:它会继续阅读页面的其余部分。 如果response元素位于页面的最后,则这将是一个可行的选择。
  • 在Home Page Reader 3.04(请注意,它是最新版本)中,位置设置不再正常工作。 读者跳回到页面顶部,而不是跳转到响应段落(我也尝试过使用location.replace进行尝试,以查看是否会有所作为,但不会如此)。
  • 在Hal 6.5和Connect Outloud 2.0中,阅读器会宣布一个新的页面加载,但随后在响应后从元素开始读取,完全丢失了响应。
  • 在JAWS 5.0和6.2中,代码不起作用,有时甚至根本不做任何响应。 其他时间,它再次重新读取触发器链接文本或顶级标题; 偶尔,它的行为与Hal和Connect Outloud相同。
  • 在Windows Eyes 5.0中,内容会更新! 但除此之外,它的行为方式类似于Home Page Reader 3.02:它宣布一个新的页面加载,然后从(包括)响应元素开始读取。 但是,这种现象似乎并非如此:该设备只能那样工作,因为Windows Eyes在加载您之前访问过的页面时会记住您以前的位置,并且由于响应是直接在触发器之后产生的,因此您将听到下一件事。 如果不是这种情况,它将简单地读取触发器之后的内容。
  • Windows Eyes 5.5(beta)的行为与Hal和Connect Outloud完全相同。

那里存在一种模棱两可的模式,即多个设备都执行相同的操作,跳过响应段落并从其后面的元素开始。 在我看来,HTML可能是一个因素,所以我将其更改为如下形式:

<p> 
   <a name="response" id="response" href="#">
       This link will update with the response.</a>
</p>

而且,使用相同的位置设置,第二次测试的结果确实发生了变化。 即使我们不使用链接的href,它的添加也使锚点成为可聚焦的元素(段落或没有href的锚点不是),这似乎使它在某些设备上更可靠地工作。

修改后的第二项测试的结果

两种版本的Home Page Reader的行为均与以前相同,并且由Connect Outloud加入,Connect Outloud现在的行为类似于HPR 3.02(它可以工作,但仍在进行读取)。 现在,两个版本的Windows Eyes的行为都像以前的5.5(它们在响应后开始从元素读取)。 但是在JAWS和Hal中,代码可以完美地工作-说出了响应文本,但没有任何进一步发生(尽管JAWS可能在说出响应文本之前也要先重新读取页面的顶级标题)。

第三次测试

在第三个测试中,一旦文本的文本被更新,我们将使用响应链接上的编程focus()调用替换位置设置。 新的HTML如下所示:

<p> 
   <a href="./" id="response">  
       This link will update with the response.</a>
</p>

同样,只需对原始的onreadystatechange函数进行少量修改(更改以粗体显示):

request.onreadystatechange = function() 
{
 if (request.readyState == 4
     && /^(200|304)$/.test(request.status.toString()))
 {
   response.innerHTML = request.responseText;
   response.focus();
 }
}

第三次测试的结果

该代码在JAWS 5.0和Connect Outloud之外的任何设备中均不起作用(奇怪的是,鉴于它在较早的版本中成功,因此它在JAWS 6.2中不起作用)。 无法在大多数设备上工作意味着什么都没有发生。 但是,在JAWS 6.2中,将再次说出触发链接,而Windows Eyes的行为仍与修改的第二项测试完全相同(在响应后开始从元素读取)。

第四测验

第四个测试完全取消了响应元素,而是在警报对话框中显示响应文本。 HTML只是触发器链接,而onreadystatechange函数简化为:

request.onreadystatechange = function() 
{
 if (request.readyState == 4
     && /^(200|304)$/.test(request.status.toString()))
 {
     alert(request.responseText);
 }
}

第四次考试的结果

这对每个人都应该是安全的,但令人惊讶的是,事实并非如此:Windows Eyes 5.0并不总是说对话框文本。 有时,它只是宣布对话框,而没有告诉您对话框的内容!

第五测验

对于第五项测试,我们将继续构成元素。 首先,我们将尝试更新和关注文本字段:

<form action=""> 
 <div>
   <input type="text" id="response" size="50"
       value="This field will update with the response">
 </div>
</form>

这是适用的onreadystatechange函数:

request.onreadystatechange = function() 
{
 if (request.readyState == 4
     && /^(200|304)$/.test(request.status.toString()))
 {
   response.value = request.responseText;
   response.focus();
 }
}

第五次考试的结果

此测试在Home Page Reader或Hal中不起作用(尽管有典型的视觉响应,但什么也没有发生)。 它在JAWS 6.2中也失败,与第三个测试一样,它再次重复触发链接,并且也可能重新声明顶级标题。

该代码在Windows Eyes中也失败,其行为与第三次测试的行为相同(即,它在响应后开始从元素读取)。 可以使用此代码的唯一读者是JAWS 5.0和Connect Outloud,尽管他们也说“ edit”以在说出其值之前宣布编辑框。

第六次考试

在第六次测试中,我们将做几乎相同的事情。 但是,这一次,我们将以编程方式选择其文本,而不是集中该元素:

request.onreadystatechange = function() 
{
 if (request.readyState == 4
     && /^(200|304)$/.test(request.status.toString()))
 {
   response.value = request.responseText;
   if (typeof response.createTextRange != 'undefined')
   {
     var range = response.createTextRange();
     range.select();
   }
   else if (typeof response.setSelectionRange != 'undefined')
   {
     response.setSelectionRange(0, response.value.length);
   }
 }
}

第六次考试的结果

这里的成功和失败模式与先前的测试相同。
在第七个也是最后一个测试中,我们将对response元素使用一个按钮:

<form action=""> 
 <div>
   <button type="button"
     id="response">This button will update with the response
   </button>
 </div>
</form>

然后,我们将更改按钮文本并将其焦点对准,就像我们在第五次测试中所做的一样:

request.onreadystatechange = function() 
{
 if (request.readyState == 4
     && /^(200|304)$/.test(request.status.toString()))
 {
   response.firstChild.nodeValue = request.responseText;
   response.focus();
 }
}

第七次考试的结果

此测试也产生与第五和第六次测试相同的结果,但是与预期的微小变化相比,JAWS 5.0和Connect Outloud(在其中起作用)通过在文本后说“按钮”而不是“编辑”来宣布响应小部件。 ”之前。

结论

似乎没有任何可靠的方法可以通知屏幕阅读器DOM中的更新。 有一些适用于一台或多台设备的零散方法,但是没有全面的方法或组合可以覆盖所有设备,因为即使是不起眼的警报也可能无法在Windows Eyes中正常工作。
那么这对我们作为开发人员意味着什么–是否意味着我们应该停止使用AJAX技术?

是?

让我们面对现实吧,很多AJAX应用程序(我敢说是“最多”吗?)出于自己的目的而使用这种方法,并没有真正从中受益,它们也可以使用传统的POST和响应。

我什至更进一步呼吁在这里对我们的优先事项进行根本性的重新评估。 我们正在谈论的是使动态客户端界面在屏幕阅读器中有效地工作,但这也许不是重点。 使应用程序本身在屏幕阅读器中有效运行不是真正的意义吗?

交互只是细节,也许我们实际上一直在将自己的愿望和偏好投射到与他们并不相关的用户身上。 动态客户端界面可能根本无法使屏幕阅读器用户受益。 也许真正适合他们的是扮演最初为读者构建的任务:单个页面请求以及HTTP的交互。 这些恰好是屏幕阅读器旨在处理的那种交互。

没有?

也许我们应该让使用屏幕阅读器的人关闭JavaScript,直到该技术可以完成任务为止。 或者,也许我们应该在应用程序的开头添加用户首选项,以便用户可以预先选择他们所选择的界面。 如果我们可以确信屏幕阅读器用户根本没有JavaScript,那么我们可以设计适用于他们的非脚本功能,就像任何非脚本用户一样,都可以使用POST /响应范例。

但是不可否认的是,某些AJAX应用程序只能以这种方式工作-在某些情况下,不可能提供不依赖JavaScript的真正等效的替代方法。 (Gmail是一个很好的例子:它提供了无脚本版本,但功能远不如其脚本等效版本。)也许我们应该考虑筛选阅读器供应商本身,因为可以合理地期望它们对这种增长做出响应通过提供必要的挂钩和反馈来使远程脚本可供用户使用,远程脚本的普及。

IBM当前正在与GW Micro(Windows Eyes的制造商)和Mozilla Foundation合作,引入“角色”和“状态”(由元素属性定义),以传达有关元素的性质和状态的信息 。 从理论上讲,这完全解决了问题,并且意味着任何适当的元素都可以传达所有必要的信息:其自身的含义,其行为角色以及其当前状态。

但是,尽管这些都是令人兴奋的发展,但我们现在还不能真正使用它,因为它不向后兼容:除了Internet Explorer或Firefox之外,它根本没有为其他浏览器提供任何功能,而为Firefox以外的设备组合仅提供了非常有限的功能1.5加上Windows Eyes 5.5。

所以?

我不得不得出一个结论,除非找到一种方法可以将更新的内容通知屏幕阅读器,否则AJAX技术不能被认为是可访问的,并且如果没有向用户提供真正等效的非脚本替代方法,则不应在生产站点上使用AJAX技术。前期。

但是,我自由而愉快地承认,我只分析了有限的一些测试-我已经涵盖了所有可以想到的角度,但是我敢肯定,还有很多其他想法,我们只需要其中一个出来!

因此,如果您认为我太容易放弃了,请考虑将其称为“召唤武器”: 让我们找到一种使之工作的方法!

From: https://www.sitepoint.com/ajax-screenreaders-work/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值