通过 WebView 以编程方式触发 Android TalkBack 文本

Bar*_*der 7 javascript android accessibility webview talkback

所以我一直在努力让一个带有一些文本的 Android WebView 更容易被盲人用户访问,我想知道是否有可能触发 Android TalkBack 自动说出一些文本?

我在想一个这样的链接:

<a href="#" id="flubble">Flubble</a>
Run Code Online (Sandbox Code Playgroud)

还有一个像这样的元素:

<a href="#" id="bibble">Bibble</a>
Run Code Online (Sandbox Code Playgroud)

然后使用焦点事件自动读取链接中的文本:

document.getElementById("flubble").addEventListener("click", function(event) {
    event.preventDefault();
    document.getElementById("bibble").focus();
    //I want it to say "bibble" here
});
Run Code Online (Sandbox Code Playgroud)

本质上,当它聚焦时,我希望它说出文本?有什么办法可以实现这种“自动对讲”功能?

干杯 <3

Gra*_*hie 5

简答

使用视觉上隐藏的aria-live区域并将相关文本复制到该区域。此外,对交互式内容使用<button>not a <a href="#"

长答案

在没有明确目的的情况下混淆用户焦点(例如在打开时将关闭按钮聚焦在模式中)......坏主意,你最不想做的事情就是让用户失去他们在页面上的位置。

此外,这意味着您需要在tabindex="-1"整个页面上在您想要读取的通常不会获得焦点的任何元素上添加大量属性,从而使可维护性成为一场噩梦。

如果您想读出文本,那么我建议您使用一个aria-live区域。

aria-liveon 元素旨在大声说出该元素中包含的任何内容。每次元素的内容更新时都会发生这种情况。

您会注意到我添加了,aria-live="polite"因为这可以确保他们的公告不会中断页面​​上的其他公告。

为了完整起见,还有aria-live="assertive"(但你应该只真正将它用于警告和错误/状态更新之类的事情,因为它会切断任何当前所说的句子)和aria-live="off"(这对于禁用你的对讲功能很有用,因为它实际上与aria-live元素上没有)

我建议您将文本从要读出的相应元素中复制到视觉隐藏aria-live区域中。

如果您不知道视觉上隐藏的文本是屏幕上不可见的屏幕阅读器可访问文本。虽然有很多库sr-only内置了一个类,但我鼓励您使用下面小提琴中视觉隐藏类,因为我在这个答案中解释了更好的兼容性和未来证明

我还演示了如何使其在您的 Web 视图中可重用的概念,对使用 jQuery 表示歉意,这里来晚了,我想为您快速整理小提琴!

在屏幕阅读器中尝试以下内容,我认为代码是不言自明的,但任何问题都可以问。最后,根据您的“详细程度”设置,如果您将这些内容复制到aria-live区域中,第三个按钮会显示相同的内容(具有语义,例如“标题”和“链接”)……如果您没有听到这些内容设置可能需要更改。

例子

$('button').on('click', function(e){
    console.log($(this).data('target'));
    
    var targetID = $(this).data('target');
    var text = $('#' + targetID).html();
    console.log(text);
    $('.speak-aloud').html(text);
    
});
Run Code Online (Sandbox Code Playgroud)
.visually-hidden { 
    border: 0;
    padding: 0;
    margin: 0;
    position: absolute !important;
    height: 1px; 
    width: 1px;
    overflow: hidden;
    clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
    clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
    clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
    white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="visually-hidden speak-aloud" aria-live="polite"></div>

<button data-target="p2">Read text in paragraph 2</button>
<button data-target="p4">Read text in paragraph 4</button>
<button data-target="longer-text">Read the section contents</button>

<p>This is some other text</p>
<p id="p2">This is the text to be read aloud in paragraph 2</p>
<p>Some more filler text</p>
<p id="p4">paragraph 4, will be read aloud when the second button is clicked.</p>



<section id="longer-text">
<h2>Section Header</h2>
<a href="https://google.com">Go to google link for an example of more complex text</a>
</section>
Run Code Online (Sandbox Code Playgroud)

根据您的示例对语义的最后一句话。

对于可访问性 -语义很重要。

锚应该用于页面更改(或者在 SPA 中,如果整个事情是 AJAX 驱动的,则 URL 更改),按钮应该用于同一页面上的交互式内容。所以使用 a<button>而不是<a href="#">as 让屏幕阅读器用户知道会发生什么(如果我单击链接,我希望页面更改,如果我按下按钮,我希望某种形式的交互式内容)。