Skip to content

Instantly share code, notes, and snippets.

@yamoo9
Last active December 22, 2021 22:42
Show Gist options
  • Save yamoo9/8c57ada6d132a52e8c593248d9c8d697 to your computer and use it in GitHub Desktop.
Save yamoo9/8c57ada6d132a52e8c593248d9c8d697 to your computer and use it in GitHub Desktop.
focusable 또는 tabbable 할 수 있는 HTML 요소 검사 및 리스트 반환 유틸리티
/* -------------------------------------------------------------------------- */
/* FOCUSABLE (tabindex="-1" 포함) */
/* -------------------------------------------------------------------------- */
const focusableSelector = `
a[href],
area[href],
button,
input,
select,
textarea,
iframe,
summary,
details,
video[controls],
audio[controls],
[contenteditable=""],
[contenteditable="true"],
[tabindex]
`
.replace(/\n\s+/g, '')
.trim();
export const isFocusable = (elementNode) => {
const current = document.activeElement;
if (current === elementNode) return true;
const protectEvent = (e) => e.stopImmediatePropagation();
elementNode.addEventListener('focus', protectEvent, true);
elementNode.addEventListener('blur', protectEvent, true);
elementNode.focus({ preventScroll: true });
const result = document.activeElement === elementNode;
elementNode.blur();
if (current) current.focus({ preventScroll: true });
elementNode.removeEventListener('focus', protectEvent, true);
elementNode.removeEventListener('blur', protectEvent, true);
return result;
};
export const getFocusableElements = (node) => getElements(node, true);
/* -------------------------------------------------------------------------- */
/* TABBABLE (tabindex="-1" 제외) */
/* -------------------------------------------------------------------------- */
const tabbableSelector = focusableSelector.replace(
/\[tabindex\]/,
'[tabindex]:not([tabindex^="-"])'
);
export const isTabbable = (elementNode) =>
isFocusable(elementNode) && Number(elementNode.getAttribute('tabindex')) >= 0;
export const getTabbableElements = (node) => getElements(node);
/* -------------------------------------------------------------------------- */
/* GET ELEMENTS */
/* -------------------------------------------------------------------------- */
const getElements = (node, isFocusable = false) =>
Array.from(
node.querySelectorAll(isFocusable ? focusableSelector : tabbableSelector)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment