Skip to content

Instantly share code, notes, and snippets.

@izzi-ink
Created May 21, 2020 14:02
Show Gist options
  • Save izzi-ink/23360c31348225230823bee9e242d0f5 to your computer and use it in GitHub Desktop.
Save izzi-ink/23360c31348225230823bee9e242d0f5 to your computer and use it in GitHub Desktop.
Announcing the Count

Announcing the Count

Use the aria-live attribute to announce a live character and word count to screen readers such as VoiceOver on macOS.

Want to learn how to build this? Join the next session of the Vanilla JS Academy ⚓️

A Pen by Kieran Barker on CodePen.

License.

<header>
<h1>Announcing the Count</h1>
<p>
<strong>NOTE: In CodePen, the changes sometimes get announced more than once. This does not happen when I test <em>outside</em> CodePen. I think this is because CodePen runs the demo inside an <code>&lt;iframe&gt;</code>.</strong>
</p>
</header>
<main>
<label for="text">Enter your text below.</label>
<textarea id="text"></textarea>
<p id="count" aria-live="polite">You've written 0 words and 0 characters.</p>
</main>
<footer>
<p>Want to learn how to build this? Join the next session of the <a href="https://vanillajsacademy.com/">Vanilla JS Academy</a> ⚓️</p>
</footer>
//
// Variables
//
// Get the #text element
var text = document.querySelector("#text");
// Get the #count element
var count = document.querySelector("#count");
//
// Functions
//
/**
* Get the number of words in a text area
* @param {Node} textArea The text area
* @returns {Number} The word count
*/
function getWordCount (textArea) {
// Trim whitespace from the value
var value = textArea.value.trim();
// If it's an empty string, return zero
if (!value) return 0;
// Otherwise, return the word count
return value.split(/\s+/).length;
}
/**
* Get the number of characters in a text area
* @param {Node} textArea The text area
* @returns {Number} The character count
*/
function getCharacterCount (textArea) {
return textArea.value.length;
}
/**
* Update the word and character counts
*/
function updateCounts () {
count.textContent = (
"You've written " + getWordCount(this) + " words " +
"and " + getCharacterCount(this) + " characters."
);
}
//
// Inits & Event Listeners
//
// Update both counts when the value of #text changes
text.addEventListener("input", updateCounts);
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
* {
box-sizing: border-box;
}
body {
width: 88%;
max-width: 30em;
margin: 1em auto;
line-height: 1.5;
background-color: aliceblue;
font-family: "Roboto", sans-serif;
}
h1 {
font-weight: normal;
}
label {
display: block;
}
textarea {
width: 100%;
min-height: 7em;
padding: .5em;
border: .125em solid #d7d7d7;
border-radius: .25em;
background-color: white;
font: inherit;
}
textarea:focus {
outline: .125em solid #ffd346;
}
strong {
font-weight: bold;
}
a {
color: #068;
}
a:hover {
text-decoration: none;
}
footer {
border-top: .5em solid #d7d7d7;
margin-top: 2em;
}
<link href="https://fonts.googleapis.com/css2?family=Roboto&amp;display=swap" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment