HTML 具有输入范围的音频辅助功能
HTML Audio accessibility with Input Range
最小问题示例:https://codepen.io/sidouglas/pen/LYPZaOG
当输入范围 集中 时,使用 Chrome Vox 或 Mac 的画外音 — [= 的每个值15=]连续读出。
<input
...
v-bind:aria-valuemax="valueMax"
v-bind:aria-valuenow="valueNow"
v-bind:aria-valuetext="currentTime + ' of ' + totalDuration"
...
/>
将此与非常易于访问的 https://plyr.io/#audio 组件进行对比 - 当获得焦点时,它会继续更新其 aria 值,但只向屏幕宣布 reader 两次。
有谁知道 plyr 是怎么做到的?
new Vue({
el: '#range',
data: {
valueMax:100,
duration:100,
current:0,
totalDuration:'1:40'
},
computed:{
currentTime: function() {
return this.convertTime(this.current);
},
valueNow() {
return Math.round(this.current);
},
},
methods: {
convertTime(time) {
const minutes = Math.floor(time / 60);
const seconds = time - (minutes * 60);
return `${minutes}:${seconds.toFixed(0).toString().padStart(2, '0')}`;
},
},
mounted: function(){
var self = this;
setInterval(function(){
self.current = Number(self.current) + 1;
if(self.current >= self.valueMax){
self.current = 0;
}
},2000);
},
});
.audio-file-player__slider-range{
border:1px solid red;
width:100%;
}
.audio-file-player__slider-range:focus {
box-shadow: 0 0 10px blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="range">
<input
aria-label="Seek"
aria-valuemin="0"
autocomplete="off"
class="audio-file-player__slider-range u-color-gray-111111 u-width-100"
min="0"
role="slider"
step="1"
type="range"
v-bind:aria-valuemax="valueMax"
v-bind:aria-valuenow="valueNow"
v-bind:aria-valuetext="currentTime + ' of ' + totalDuration"
v-bind:max="duration"
v-model="current"
/>
<p>current: {{ current }}</p>
<p>aria-valuenow: {{ valueNow }}</p>
<p>aria-valuetext: {{ currentTime + ' of ' + totalDuration }}</p>
</div>
对于任何遇到此问题的人来说,简单的解决方案是使用 aria-valuetext
覆盖该值。
当项目正在播放时,我会在 首次获得焦点 时将 aria-valuetext
设置为 'current: currentTime
, remaining: remainingTime
'。
然后在项目播放时不更新时间(让 aria-valuetext
保持不变)。
然后当播放暂停/停止时再次更改 aria-valuetext
以反映当前时间。
最后,当有人使用箭头键进行搜索时,我会在 200 毫秒的节流阀上更新当前时间。
您可以决定是在玩游戏时执行此操作还是仅在不玩游戏时执行此操作,因为我不确定在信息与中断方面哪个是最佳解决方案。
我倾向于在玩游戏时不更新,因为如果您使当前时间可聚焦,用户始终可以切换到当前时间。
这样做可以确保它不会干扰播放音乐或播报 200 次不同的时间。
plyr.io理论 - 一开始我也重复了,然后我改变了我的宣布速度设置。我相信有些人收到通知而有些人没有收到通知的原因是他们更新当前时间的速度(看起来像每秒 3-4 次)而且我认为重复的速度如此之快以至于屏幕 Reader决定不将用户与它混淆。只是一个理论,但我最好的猜测,因为他们没有做任何我能看到的聪明事。
将您的歌曲路径转换为计算 属性 然后获取其当前时间。如下所示:
<template>
<div>
<h3>Audio Player Test</h3>
<audio
ref="myMusic"
src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
@timeupdate="onTimeUpdateListener"
></audio>
{{currentTime}}
<button @click="play">Play</button>
<button @click="pause">Pause</button>
</div>
</template>
data() {
return {
songCurrent: 0,
currentTime: "00:00" // The initial current time
};
},
computed: {
song() {
return this.$refs.myMusic;
}
}
methods: {
play() {
this.song.play();
},
pause() {
this.song.pause();
},
onTimeUpdateListener: function() {
// Update current time
this.currentTime = this.$refs.myMusic.currentTime;
}
}
最小问题示例:https://codepen.io/sidouglas/pen/LYPZaOG
当输入范围 集中 时,使用 Chrome Vox 或 Mac 的画外音 — [= 的每个值15=]连续读出。
<input
...
v-bind:aria-valuemax="valueMax"
v-bind:aria-valuenow="valueNow"
v-bind:aria-valuetext="currentTime + ' of ' + totalDuration"
...
/>
将此与非常易于访问的 https://plyr.io/#audio 组件进行对比 - 当获得焦点时,它会继续更新其 aria 值,但只向屏幕宣布 reader 两次。
有谁知道 plyr 是怎么做到的?
new Vue({
el: '#range',
data: {
valueMax:100,
duration:100,
current:0,
totalDuration:'1:40'
},
computed:{
currentTime: function() {
return this.convertTime(this.current);
},
valueNow() {
return Math.round(this.current);
},
},
methods: {
convertTime(time) {
const minutes = Math.floor(time / 60);
const seconds = time - (minutes * 60);
return `${minutes}:${seconds.toFixed(0).toString().padStart(2, '0')}`;
},
},
mounted: function(){
var self = this;
setInterval(function(){
self.current = Number(self.current) + 1;
if(self.current >= self.valueMax){
self.current = 0;
}
},2000);
},
});
.audio-file-player__slider-range{
border:1px solid red;
width:100%;
}
.audio-file-player__slider-range:focus {
box-shadow: 0 0 10px blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="range">
<input
aria-label="Seek"
aria-valuemin="0"
autocomplete="off"
class="audio-file-player__slider-range u-color-gray-111111 u-width-100"
min="0"
role="slider"
step="1"
type="range"
v-bind:aria-valuemax="valueMax"
v-bind:aria-valuenow="valueNow"
v-bind:aria-valuetext="currentTime + ' of ' + totalDuration"
v-bind:max="duration"
v-model="current"
/>
<p>current: {{ current }}</p>
<p>aria-valuenow: {{ valueNow }}</p>
<p>aria-valuetext: {{ currentTime + ' of ' + totalDuration }}</p>
</div>
对于任何遇到此问题的人来说,简单的解决方案是使用 aria-valuetext
覆盖该值。
当项目正在播放时,我会在 首次获得焦点 时将 aria-valuetext
设置为 'current: currentTime
, remaining: remainingTime
'。
然后在项目播放时不更新时间(让 aria-valuetext
保持不变)。
然后当播放暂停/停止时再次更改 aria-valuetext
以反映当前时间。
最后,当有人使用箭头键进行搜索时,我会在 200 毫秒的节流阀上更新当前时间。
您可以决定是在玩游戏时执行此操作还是仅在不玩游戏时执行此操作,因为我不确定在信息与中断方面哪个是最佳解决方案。
我倾向于在玩游戏时不更新,因为如果您使当前时间可聚焦,用户始终可以切换到当前时间。
这样做可以确保它不会干扰播放音乐或播报 200 次不同的时间。
plyr.io理论 - 一开始我也重复了,然后我改变了我的宣布速度设置。我相信有些人收到通知而有些人没有收到通知的原因是他们更新当前时间的速度(看起来像每秒 3-4 次)而且我认为重复的速度如此之快以至于屏幕 Reader决定不将用户与它混淆。只是一个理论,但我最好的猜测,因为他们没有做任何我能看到的聪明事。
将您的歌曲路径转换为计算 属性 然后获取其当前时间。如下所示:
<template>
<div>
<h3>Audio Player Test</h3>
<audio
ref="myMusic"
src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
@timeupdate="onTimeUpdateListener"
></audio>
{{currentTime}}
<button @click="play">Play</button>
<button @click="pause">Pause</button>
</div>
</template>
data() {
return {
songCurrent: 0,
currentTime: "00:00" // The initial current time
};
},
computed: {
song() {
return this.$refs.myMusic;
}
}
methods: {
play() {
this.song.play();
},
pause() {
this.song.pause();
},
onTimeUpdateListener: function() {
// Update current time
this.currentTime = this.$refs.myMusic.currentTime;
}
}