技术分享 | 如何开发一个测试答题类无障碍H5?

2022年01月07日 2284阅读

H5是大家常用的一种传播工具,它方式灵活、互动性强且传播速度快,配合优秀的创意内容能够迅速在用户中形成裂变传播。

但往往很多开发者在制作H5时,并未考虑到无障碍这一点,导致障碍用户(尤其是视障用户)无法顺畅地浏览H5并进行交互、传播,也让H5白白损失了一大波用户。

那么,应该如何开发一个无障碍H5呢?今天,我们以2021年国际残疾人日当天在朋友圈圈粉无数的“123无障爱”活动H5为例,通过实际经验来为大家介绍如何开发一个较为基础的测试答题类无障碍H5,让它能够被视障用户浏览使用。

图:“123无障爱”活动H5二维码,可以长按识别二维码体验

“123无障爱”活动H5是一款测试答题类H5,需要用户进行选项答题,并根据答题情况匹配对应的结果,同时生成海报进行下一轮传播。所以,这款H5在无障碍方面的挑战主要是在保持界面美观的前提下,让用户顺畅获取H5所有展示信息、顺畅交互(答题、切换页面等)。

H5策划时期,绝大多数策划者都会遵循美观的原则进行策划设计,并保持整体H5视觉的统一性,所以H5中几乎所有素材都是配套的图片素材,这就导致所有的内容使用屏幕阅读器的用户是无法获取的。

同时,使用一些自定义组件也会有无障碍问题,像基于VUE的UI库的无障碍其实并不太理想,可能无法直接使用。

接下来,让我们结合“123无障爱”活动H5的开发过程,看一看如何进行H5无障碍优化。

注:以下参考代码片段的开发环境为Vue2.x和微信内置浏览器测试结果,其他环境可能略有不同。

首先,需要为所有包含文字或交互内容的图片添加上可以被屏幕阅读器识别的元素。

我们来看一段代码片段。

1<!--html片段-->

2<img alt="第一题,你会在意每天的穿搭吗?">

大家可以看到,想要解决图片朗读的问题是非常简单的,我们只要给img标签添加alt属性即可实现。当然了,我们H5里面的所有按钮也都设置了背景图片,对于Button而言也只需要添加aria-label即可。

其次,解决完图片朗读后,接下来需要处理的就是每道题的选中状态了。

图:问答题选中某个选项后此选项会高亮显示

前文提到过,为了美观和整体的统一性,H5所用素材都是图片,包括选项题的选项也是使用图片代替的,这就导致选项本身并不是一个Radio(单选框),自然也不存在被选中的状态,上图的选中状态是我们用了两张图片进行模拟的,当点击某个选项后,立即替换为另一张选中的图片实现的效果。对于读屏模式下的视障用户而言,自然无法知道当前图片模拟的选项是否是选中状态了。

要解决此问题也很简单,我们来看下具体的代码思路。

1<!--html片段-->

2<div>

3<img @click="problema_btn()" :aria-checked="problema_checked" role="radio" alt="A,是,我精心挑选每天穿的衣服"/>

4</div>

5<div>

6<img @click="problemb_btn()" :aria-checked="problemb_checked" role="radio" alt="B,不是,随便套件衣服就足够了"/>

7</div>

8<div>

9 <img @click="problemc_btn()" :aria-checked="problemc_checked" role="radio" alt="C,非必要不穿衣服"/>

10</div>

11<!--JavaScript片段-->

12<script>

13//......

14data() {

15 return {

16 problema_checked: false,

17 problemb_checked: false,

18 problemc_checked: false,

19 }

20},

21methods: {

22/**这里只列举选项A的点击事件,选项B和C只需要相同处理即可*/

23  problema_btn() {

24 this.problema_checked = true

25 this.problemb_checked = false

26 this.problemc_checked = false

27 //......

28 },

29}

30</script>

大家可以看到,我们给img标签添加了alt,告诉屏幕阅读器当前选项的内容是什么,然后我们添加了role="radio",这是告诉屏幕阅读器当前的控件类型是radio而不是img,因为radio才会有选择的状态而img是没有的,其次我们还添加了aria-checked="problema_checked",这是告诉屏幕阅读器当前的选中状态,如果为True则为选中,如果为False则没有选中,problema_checked这个变量是我们在data中定义的,当点击第一个选择时触发problema_btn()方法,在此方法中将this.problema_checked变量的值设置为True,此时屏幕阅读器就可以获取到当前的选项的选中状态了。

接下来我们还需要解决一个问题,当用户切换路由时,进入到新页面后我们希望将屏幕阅读器的焦点停留在当前页面的题目上以便用户有更好的体验,我们来看下代码是如何实现的。

1<!--html片段-->

2<p tabindex="1" id="title-p" aria-label="第一题,你会在意每天的穿搭吗?">

3 <el-image aria-hidden="true" src="、xxx"></el-image>

4</p>

5<!--JavaScript片段-->

6<script>

7//......

8mounted() {

9 this.$nextTick(function () {

10 document.getElementById('title-p').focus()

11 }

12}

13</script>

可以看到我们添加了一个tabindex="1"(该页面仅有1个标签设置了tabindex属性所以此处可以为1),需要注意的是在Vue2.x环境中且在微信浏览器下运行必须要加,否则动态设置屏幕阅读器的焦点可能会失效。想要实现动态将无障碍焦点设置到这个标题上,我们需要在mounted生命周期的$nextTick(方法中设置focus()。这样当我们路由切换的第一时间无障碍焦点就可以在我们指定的位置了。

大家可以注意到,我们设置的无障碍焦点是给p标签设置的,因为img标签设置focus()是不会生效的。因此为了避免用户触摸到两个相同的焦点,我们需要屏蔽掉img的无障碍焦点,添加aria-hidden="true"属性即可。

完成上述编码后,一个较为基础的H5就可以基本满足被读屏模式下的视障用户所访问了。但同时由于H5可随意灵活搭配,在大多数情况下,可能会面临各种各样并不相同的无障碍问题,如滚动轮播图,日期时间选择,各种复杂的自定义控件等。所以如果要制作一个较为复杂的H5,想要做好无障碍还是要多下一些功夫的。

在此,我们也呼吁大家多多分享自己的无障碍实操经验,帮助更多想要做无障碍或不知如何进行无障碍的朋友答疑指路,共同帮助行业良性可持续发展。

以上就是今天和大家分享的内容,如有更多想要沟通交流的内容,欢迎在下方评论区留言。

作者:周富贵

编辑:幽默丝

END