
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();
}
}
}
}
popup.style.display !== "block" → 닫혀 있으면 실행하지 않음querySelectorAll()을 사용해 요소를 찾고 배열로 저장focusableElements[0]: 첫 번째 요소focusableElements[focusableElements.length - 1]: 마지막 요소Shift + Tab: 첫 번째 요소에서 이전으로 이동 시 마지막 요소로 포커스 이동Tab: 마지막 요소에서 다음으로 이동 시 첫 번째 요소로 포커스 이동trapFocus(event)를 사용해 포커스가 팝업 내부에서만 순환하도록 설정Shift + Tab → 첫 번째 요소에서 마지막 요소로 이동Tab → 마지막 요소에서 첫 번째 요소로 이동이렇게 구현하면 팝업이 열려 있을 때 포커스가 외부로 빠져나가는 문제를 방지할 수 있다. 🚀