[javascript] WAI-ARIA 접근성을 고려한 Popup

jinwonShen·2025년 2월 11일

javascript

목록 보기
52/52
post-thumbnail

WAI-ARIA 접근성을 고려한 팝업 포커스 트랩 구현

첫 번째 포커스 요소 찾기

const focusableElements = popup.querySelectorAll(
  'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])'
);

if (focusableElements.length > 0) {
  focusableElements[0].focus();
}

설명

  • 팝업 내부에서 포커스 가능한 요소들을 찾음
    • <a> (링크)
    • <button> (버튼)
    • <input> (입력 필드)
    • <select> (드롭다운)
    • <textarea> (텍스트 입력)
    • [tabindex]:not([tabindex="-1"])tabindex="-1"이 아닌 요소
  • 가장 첫 번째 포커스 가능한 요소를 찾아 .focus() 실행

trapFocus(event) 코드

function trapFocus(event) {
  const popup = document.getElementById("popup");
  if (popup.style.display !== "block") return; // 팝업이 열려 있을 때만 실행

  const focusableElements = popup.querySelectorAll(
    'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );
  const firstElement = focusableElements[0];
  const lastElement = focusableElements[focusableElements.length - 1];

  if (event.key === "Tab") {
    if (event.shiftKey) {
      if (document.activeElement === firstElement) {
        event.preventDefault();
        lastElement.focus();
      }
    } else {
      if (document.activeElement === lastElement) {
        event.preventDefault();
        firstElement.focus();
      }
    }
  }
}

설명

  1. 팝업이 열려있는지 확인
    • popup.style.display !== "block" → 닫혀 있으면 실행하지 않음
  2. 포커스 가능한 요소 리스트 가져오기
    • querySelectorAll()을 사용해 요소를 찾고 배열로 저장
  3. 첫 번째와 마지막 포커스 요소 설정
    • focusableElements[0]: 첫 번째 요소
    • focusableElements[focusableElements.length - 1]: 마지막 요소
  4. Tab 키 이동 제한
    • Shift + Tab: 첫 번째 요소에서 이전으로 이동 시 마지막 요소로 포커스 이동
    • Tab: 마지막 요소에서 다음으로 이동 시 첫 번째 요소로 포커스 이동

최종 요약

  • 팝업 내부에서 포커스 가능한 요소들을 찾음
  • 팝업이 열릴 때 첫 번째 포커스 요소로 이동
  • trapFocus(event)를 사용해 포커스가 팝업 내부에서만 순환하도록 설정
  • Shift + Tab → 첫 번째 요소에서 마지막 요소로 이동
  • Tab → 마지막 요소에서 첫 번째 요소로 이동

이렇게 구현하면 팝업이 열려 있을 때 포커스가 외부로 빠져나가는 문제를 방지할 수 있다. 🚀

profile
하면 된다. | 좋은 FE 개발자 되기

0개의 댓글