Script of JS part for video of this chapter.
https://youtu.be/BoAsayPVogE
Over in our JavaScript, I'm going to start by creating this variable called focusedElementBeforModal
(line 2). This is where I'm going to store a reference to the element that had focus before we open the modal. When we close the modal, we want to restore focus back to this element.
Then I'm going to use document.querySelector
to select both my modal
and my modal-overlay
(line 5, 6). I'm also going to sue querySelector
to select my modalToggle
button (line 8). And I'm going to add an eventListener
to modalToggle
to listen for the click
event, which is going to run this openModal
function (line 9).
Inside of the openaModal
function we're going to take that focusedElementBeforeModal
reference and we're going to grab the document.activeElement
and store it there (line 13).
We're going to listen for keydown
events (line 16). And call this trap keyboard function(trapTabKey
), which I'll get t in a moment. We're also going to listen to indicators for us to close our modal(closeModal
). So, if someone clicks on modalOverlay
, we're going to close the modal(closeModal
, line 19). And if someone clicks on the signUpBtn that's contained within the modal (line 21), we're also going to close the modal(closeModal
, line 22).
And the next thing we're going to do, is we're going to try and figure out all the focusable children that are inside of the modal dialogue. To do this I'm going to create this huge query string of potentially focusable elements (focusableElementsString
, line 25). And I'm going to call modal.querySelectorAll
using that string. So this should give me a grouping of everything within my modal window that could possibly receive focus. And what I want to do, is I want to figure out what the first element in that group is (line 30). And what the last element in that group is (line 31). And the idea here is these can act sort of like sentinel elements. So, if the user is tabbing through the modal window and they reach the last focusableElement
or thelastTabStop
. And they press Tab again, we're going to loop them around and put them on the firstTabStop
. Similarly, if they're on the firstTabStop
, and they press Shift+Tab, we're going to loop them around and put them on the lastTabStop
.
Next, we're just going to tell the modal
window to display itself. So we'll set its style to display block. And we'll also set the modalOverlay
to display block (line 34, 35). And then we're going to focus that firstTabStop
child inside of it (line 38). Now from this point on, if the user starts to press a key on their keyboard, we're going to check to see if they've hit the Tab key (line 42). Now using a modifier key, they could have hit Shift+Tab (line 45). And if they've hit Shift+Tab, what we're going to do, is we're going to first figure out, are they currently on the firstTabStop
? (line 46) If they are, let's wrap them around to the lastTabStop
and call focus
(line 48). If they haven't hit a modifier key and they've just hit Tab by itself (line 52), then we'll say, are they currently on the lastTabStop? (line 53) If they are, we're going to wrap them around to the firstTabStop and focus it (line 55).
Now we're also going to add a listener for the Escape key (line 61). So if they've hit the Escape key, we're just going to go ahead and close the modal (closeModal()
, line 62).
The closeModal
method is pretty straightforward (line 67). We're going to tell the modal to dispaly none (line 69). We'll tell the overlay to display none (line 70). And then we'll use that reference for that first focused element (line 73). And we're going to call focus on it again to restore focus. So in this case, it'll restore focus back to that open modal toggle button.
Now I realize this is a tone of code. I sort of think of the accessible modal window as one of the boss battles in accessibility.