In this lesson, we are using HTML, accessibility concepts, and ARIA attributes to improve the time scrubber feature of an audio player.
The goal is to make it accessible to users of screen readers so that the time scrubber announces the actual time (e.g. 12 minutes and 15 seconds) rather than just the value (e.g. 735).
We are also creating a new folder called "helpers" in the "src" folder and a new file called "format time.js" within it to hold a function called "format human read time" that takes time as a parameter and returns the human-readable equivalent of that time. Additionally, the author debugs the code and uses console.log to check the variable.
Think about: Why does a human-readable name help?
[0:00] As you can see, we've been using a lot of native HTML to create an audio player. We've also been using some accessibility concepts to rename some of these buttons. Now let's improve the time scrubber slightly. So if we inspect this element, you can see that we have a value, we have a max and we have a min. All of these attributes are absolutely necessary in order to have an accessible input range. However, if we were using a screen reader, we wouldn't want that to announce something like 735. We would want it to announce the actual time. So 12 minutes and 15 seconds. If I switch to Safari and move this time to 10.42 and then turn on voiceover. [0:42] Voiceover on Safari, React app in React app, web content, heading left, end of main, play elapsed time 10.40 total time 25.58 scrubber, 642 scrubber slider.
[0:56] You are currently on voiceover off. You'll see that this announces as 642 instead of 10 minutes and 42 seconds. That's because the value of that element is 642. So what can we do about this? If we go to MDN docs, there is a ARIA attribute called ARIA value text. The definition says the ARIA value text attribute defines the human readable text alternative for ARIA value now. ARIA value now is the equivalent of the value on an input range. With this information, we can use ARIA value text on our time scrubber and create another formatter to help to create that human readable value. The first thing I'm going to do is in the SRC folder, I am going to create a new folder and call it helpers. Inside that folder, I'm going to create a new file called format time dot JS. Because we're going to have a couple of formatters, I am going to take this format time function from the audio player dot JS file and move it to the format time file with an export. Now we obviously need to import format time from helpers format time dot JS. Now we're going to create a function called format human read time. And we're going to create a arrow function passing the time as a parameter. Because format time is already doing a lot of work for us, let's just use that const formatted time equals format time time. I'm a big fan of debugging as I go along, so I'm going to just console log formatted time. Then I'm going to import that format human read time into audio player. And then I am going to call it on some big number like 1000. And let's see what happens. It is working properly. Now we are going to create a time array. So const time array equals formatted time. And then we're going to split with that colon. Let's console log the time array. That is working as we expect. Now let's map through those items and change them back to numbers, map through those items, pass in the time and then parse float time. Now if we return back to the console log, those are now numbers. We're going to define a few variables here called let string and this is going to be the string that we pass back.
[3:12] Then we'll do let minutes let seconds. What we want to make sure we're doing here is if the time array length is greater than two, meaning that we will have hours included, we will add to the string. So plus equals, we're going to use a string literal and we're going to pass in time array and going to do time array at the zero index space. And then we're going to do a ternary here. So time array zero equals one. We're going to only say hour. Otherwise we'll say hours. And then we are going to add a comma after that and a space. So now we'll set minutes to be time array in the index of one and seconds to be the time array in index of two. Now let's finish out the if statement with an else. If we don't have hours, minutes is going to be time array at the index of zero and seconds will be the time array at the index of one. So now let's build out that string. So string, we're going to be adding to the string. So we'll do a plus sign equals and then we'll add a template literal. So first we'll add the minutes. So we'll do pass in the minutes variable. Next, we'll do the same thing that we did up here for the hours. We'll do another ternary. Minutes is equal to one. We'll pass in the string minutes. Otherwise it'll be minutes and we'll also use a comma and a space. And then we will add the second to that string using that shorthand, another template literal. And then we'll do that ternary again. So seconds equals one. We'll return second. Otherwise we'll return seconds. Next, we'll return string.
[4:57] So in that audio player file, let's go to the range scrubber and then we'll say aria value text pass in format human read time and the media time. Now if we go back to Safari, you'll see that we have that aria value text. And now let's run a quick test on it with VoiceOver.
[5:17] VoiceOver on Safari. React app. React app in React app. Web content. Heading level end of fan. Main. Play. Elapsed time. Total time. Scrubber. 10 minutes. 42 seconds. Scrubber. Slider.
[5:30] You. VoiceOver off. To summarize, we moved this format time into a helper and then added a format human read time function. We use that function to create a string that announces a human readable time. And then we added aria value text onto the input range for the time scrubber. And we added the format human read time and we pass in the media time.