Skip to content

Instantly share code, notes, and snippets.

@mrtag23
Created July 7, 2020 21:14
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 mrtag23/6444c29b90bf9dcac6331bce1995dd7d to your computer and use it in GitHub Desktop.
Save mrtag23/6444c29b90bf9dcac6331bce1995dd7d to your computer and use it in GitHub Desktop.
/*
Creates a focus trap inside the specified trap wrapper element.
- trapWrapper: DOM node inside which the focus should be trapped.
- customFocusableFirst: a custom DOM node(usually outside the trapWrapper)
which should be treated as a first focusable element.
- customFocusableLast: a custom DOM node(usually outside the trapWrapper)
which should be treated as the last focusable element.
- closeButton: DOM node, if provided will be used to remove focus trap event listeners.
- customEventContainer - DOM node container to be used as event listener.
*/
export function focusTrap(
trapWrapper,
customFocusableFirst,
customFocusableLast,
closeButton,
customEventContainer
) {
const focusableElements = trapWrapper.querySelectorAll('a[href]:not([disabled]), button:not([disabled])');
const firstFocusable = customFocusableFirst || focusableElements[0];
const lastFocusable = customFocusableLast || focusableElements[focusableElements.length - 1];
const KEYCODE_TAB = 9;
const eventListenerContainer = customEventContainer || trapWrapper;
function manipulateFocus(e) {
const isTabPressed = (e.key === 'Tab' || e.keyCode === KEYCODE_TAB);
if(!isTabPressed) {
return;
}
if (e.shiftKey) {
// Covers the shift + tab case.
if (document.activeElement === firstFocusable) {
lastFocusable.focus();
e.preventDefault();
}
} else {
// Covers the tab case.
if (document.activeElement === lastFocusable) {
firstFocusable.focus();
e.preventDefault();
}
}
}
eventListenerContainer.addEventListener('keydown', manipulateFocus);
if(closeButton) {
closeButton.addEventListener('click', function () {
eventListenerContainer.removeEventListener('keydown', manipulateFocus);
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment