Skip to content

Instantly share code, notes, and snippets.

@anuk79
Last active May 9, 2020 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anuk79/e201d775725b6779e5e004b976835411 to your computer and use it in GitHub Desktop.
Save anuk79/e201d775725b6779e5e004b976835411 to your computer and use it in GitHub Desktop.
// helper function to get all focusable elements in the context provided in arguments
function getFocusable(context = 'document') {
let focusable = Array.from(context.querySelectorAll('button, [href], select, textarea, input:not([type="hidden"]), [tabindex]:not([tabindex="-1"])'));
return focusable;
}
// get the first focusable element within a context
export function getFirstFocusable(context = 'document') {
let focusable = getFocusable(context);
return focusable[0];
}
// save the current active element before opening the modal
let previousActiveElement = document.activeElement;
// open the modal
// get first focusable element in modal, and move focus to it
getFirstFocusable(modal).focus();
// close the modal
// transfer the focus back to saved element when the modal is closed by user
previousActiveElement.focus();
/**
* Traps the tab key inside of the context, so the user can't accidentally get stuck behind it.
*
* Note that this does not work for VoiceOver users who are navigating with the VoiceOver commands,
* only for default tab actions. We would need to implement something like the inert attribute for that
* (see https://github.com/WICG/inert)
*/
export function trapTabKey(e, context) {
if (e.key !== 'Tab') return;
let focusableItems = getFocusable(context);
let focusedItem = document.activeElement;
let focusedItemIndex = focusableItems.indexOf(focusedItem);
if (e.shiftKey) {
if (focusedItemIndex == 0) {
focusableItems[focusableItems.length - 1].focus();
e.preventDefault();
}
} else {
if (focusedItemIndex == focusableItems.length - 1) {
focusableItems[0].focus();
e.preventDefault();
}
}
}
// reference - https://benrobertson.io/accessibility/javascript-accessibility
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment