最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Making a screen reader reread if the aria-label changes - Stack Overflow

programmeradmin9浏览0评论

Is it possible to make a screen reader reread the select element if the contents of the aria-label changes?

I've made a simple snippet, I know I'm not following most aria conventions, to show what I mean.

If you turn on a screen reader and click on the div it will read the label "unchecked" if you then press space the label will update but the screen reader will stay silent. Though it will read the new label if you click off and on again.

Is this the right way to make the screen reader read updates or is there another method I'm not aware of?

let toggleSwitch = document.querySelector('.toggle-switch');

toggleSwitch.addEventListener("keyup", function(e) {
  let code = (e.keyCode ? e.keyCode : e.which);
  
  if (code == 32) {
    let nextState = toggleSwitch.getAttribute('aria-label') == 'unchecked' ? 'checked' : 'unchecked';
    
    toggleSwitch.setAttribute('aria-label', nextState);
    
  }
})
.toggle-switch {
  width: 50px;
  height: 50px;
}

.toggle-switch[aria-label="unchecked"] {
  background: red;
}

.toggle-switch[aria-label="checked"] {
  background: green;
}
Press space to change state
<div class="toggle-switch" tabindex="0" aria-label="unchecked"></div>

Is it possible to make a screen reader reread the select element if the contents of the aria-label changes?

I've made a simple snippet, I know I'm not following most aria conventions, to show what I mean.

If you turn on a screen reader and click on the div it will read the label "unchecked" if you then press space the label will update but the screen reader will stay silent. Though it will read the new label if you click off and on again.

Is this the right way to make the screen reader read updates or is there another method I'm not aware of?

let toggleSwitch = document.querySelector('.toggle-switch');

toggleSwitch.addEventListener("keyup", function(e) {
  let code = (e.keyCode ? e.keyCode : e.which);
  
  if (code == 32) {
    let nextState = toggleSwitch.getAttribute('aria-label') == 'unchecked' ? 'checked' : 'unchecked';
    
    toggleSwitch.setAttribute('aria-label', nextState);
    
  }
})
.toggle-switch {
  width: 50px;
  height: 50px;
}

.toggle-switch[aria-label="unchecked"] {
  background: red;
}

.toggle-switch[aria-label="checked"] {
  background: green;
}
Press space to change state
<div class="toggle-switch" tabindex="0" aria-label="unchecked"></div>

Thanks for your help.

Share Improve this question asked Feb 2, 2018 at 16:29 Andrew BoneAndrew Bone 7,2912 gold badges20 silver badges34 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 16

I currently work in web accessibility. Your element does not need to read the update on the fly to be compliant with WCAG2.0 (AA), as long as the correct state is being read to the user when they navigate back to the element, that's fine!

However, if you do want it to read out the state of the div after the user activates it with space or enter, I'd probably suggest creating a screen reader only div and include aria-live="polite", then inject your changed state into that.

Typically you'd create a screen reader only class with something along the lines of this:

.sr-only {
  position: absolute;
  left:-99999px;
  height: 1px;
  width: 1px;
  overflow: hidden;
}

Aria-live will alert the user to any text updates in this "live" region as they occur, so when a user activates your div, update the sr-only with your new state (and I'd continue to update your aria-label as well so it's read out correctly if a user navigates away from the element and returns later).

Note: This won't work with your label, labels are generally only read when a user navigates to an element, so even if you just tacked aria-live onto your existing div it's not going to re-read the label to the user when updated :)

EDIT: See the fiddle below for a working example. I only have voiceover on this machine but it's quite simple and I'm fairly certain it will work with JAWS and NVDA as well.

https://jsfiddle.net/jafarian/8hck0o3m/

More info

https://www.w3.org/TR/wai-aria-1.1/#aria-live

Use these patterns to have screen readers conveniently read out the state of the control on each interaction (no JavaScript required whatsoever):

<button aria-pressed="false">Mute Audio</button>

or

<input id="my-a11y-button" type="checkbox" aria-checked="false">
<label for="my-a11y-button">Mute Audio</label>

What the example in the OP's question tries to implement is effectively a Toggle Button. The W3C has recommendations specifically for this use case: https://www.w3.org/WAI/ARIA/apg/patterns/button/

Also, generally it's good to avoid implementing accessible elements as pure <div>s, b/c for screen readers a <div> is just a logical design container that most implementation will completely ignore, even if it has aria-* attributes.

发布评论

评论列表(0)

  1. 暂无评论