Skip to content

Instantly share code, notes, and snippets.

@patrickfox
Last active February 2, 2024 17:57
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrickfox/3b143c244523b045f9f8 to your computer and use it in GitHub Desktop.
Save patrickfox/3b143c244523b045f9f8 to your computer and use it in GitHub Desktop.
Accessibility Tools: Speak text using announce()
/*
$.announce(message, method)
@param(string): message - string of text to be spoken
@param(string): method - polite(default), assertive
Problem:
Using multiple @aria-live throughout your app adds complexity and makes it more difficult to control what is spoken when.
Solution:
Using a single container w/@aria-live, any text can be spoken to the user at any time using announce()
Dependencies:
1) `.sr-only` CSS class, which makes an element not visible but still readable by screen readers:
```
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border: 0;
}
```
Demo:
http://jsfiddle.net/pfox/ou11fr9p/show/light/
Tested on:
Win 7 w/IE9 & JAWS 15
Win 7 w/FF & NVDA 2014.2
OSX Mavericks w/Safari and VO
OSX Mavericks w/Chrome and VO
OSX Mavericks w/Firefox and VO
How it works:
- Updating the contents of a container with aria-live="polite|assertive" will cause supported screen readers and browser combos to speak the updated text.
- VoiceOver will not speak duplicate text updates. For example, if we update a container with "Hello" and then "Hello" again, only the first "Hello" will be spoken.
-- To address this issue, the container is "reset" by switching the aria-live value to "off", then clearing the container contents, and then changing the aria-live value back to the desired method(polite or assertive).
*/
const announce = function(message, manners) {
let announce_timeout = null;
let announcer = document.getElementById('announce-this');
const clear_announcer = function() {
announcer.innerHTML = '';
announce_timeout = null;
return announcer;
};
manners = manners || 'polite';
if (!announcer) {
announcer = document.createElement('div');
announcer.id = 'announce-this';
document.body.appendChild(announcer);
}
announcer.setAttribute('aria-live', 'off');
clear_announcer().setAttribute('aria-live', manners);
announcer.innerHTML = message;
clearTimeout(announce_timeout);
announce_timeout = setTimeout(clear_announcer, 500);
return announcer;
};
ns.announce = announce;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment