This commit is contained in:
1 parent
c62630e22d
commit
308c06516c
142 files changed
+48475
No files matched your search
@@ -0,0 +1,84 @@
|
||||
// 헤더 로그인 팝오버 보조 스크립트
|
||||
// - 기존 CSS의 hover/focus-within 표시는 그대로 두고, 클릭(터치) 열기·바깥 클릭 닫기·Esc 닫기·aria-expanded만 보완한다.
|
||||
// - 로그인/로그아웃 링크의 주소, 문구, 노출 여부는 common.js(configureHeaderActions)가 SSO 상태에 맞춰 설정하므로 여기서 다루지 않는다.
|
||||
// - 헤더는 AJAX로 늦게 삽입되므로 document 이벤트 위임으로 처리한다.
|
||||
const WRAPPER_SELECTOR = ".header_login";
|
||||
const TRIGGER_SELECTOR = ".header_login_trigger";
|
||||
|
||||
function setExpanded(wrapper, expanded) {
|
||||
wrapper.querySelector(TRIGGER_SELECTOR)?.setAttribute("aria-expanded", String(expanded));
|
||||
}
|
||||
|
||||
function openMenu(wrapper) {
|
||||
document.querySelectorAll(`${WRAPPER_SELECTOR}.is-open`).forEach((other) => {
|
||||
if (other !== wrapper) closeMenu(other);
|
||||
});
|
||||
wrapper.classList.remove("is-dismissed");
|
||||
wrapper.classList.add("is-open");
|
||||
setExpanded(wrapper, true);
|
||||
}
|
||||
|
||||
// dismiss: hover/focus가 남아 있어도 포인터·포커스가 벗어날 때까지 닫힌 상태를 유지한다(Esc).
|
||||
function closeMenu(wrapper, { dismiss = false } = {}) {
|
||||
wrapper.classList.remove("is-open");
|
||||
wrapper.classList.toggle("is-dismissed", dismiss);
|
||||
setExpanded(wrapper, false);
|
||||
}
|
||||
|
||||
function isMenuVisible(wrapper) {
|
||||
if (wrapper.hidden || wrapper.classList.contains("is-dismissed")) return false;
|
||||
return wrapper.classList.contains("is-open") || wrapper.matches(":hover, :focus-within");
|
||||
}
|
||||
|
||||
if (!window.__baronHeaderLoginBound) {
|
||||
window.__baronHeaderLoginBound = true;
|
||||
|
||||
document.addEventListener("pointerover", (event) => {
|
||||
if (event.pointerType === "touch") return;
|
||||
const wrapper = event.target.closest?.(WRAPPER_SELECTOR);
|
||||
if (wrapper && !wrapper.contains(event.relatedTarget) && !wrapper.classList.contains("is-dismissed")) {
|
||||
setExpanded(wrapper, true);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("pointerout", (event) => {
|
||||
if (event.pointerType === "touch") return;
|
||||
const wrapper = event.target.closest?.(WRAPPER_SELECTOR);
|
||||
if (wrapper && !wrapper.contains(event.relatedTarget) && !wrapper.contains(document.activeElement)) {
|
||||
closeMenu(wrapper);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("focusin", (event) => {
|
||||
const wrapper = event.target.closest?.(WRAPPER_SELECTOR);
|
||||
if (wrapper && !wrapper.classList.contains("is-dismissed")) setExpanded(wrapper, true);
|
||||
});
|
||||
|
||||
document.addEventListener("focusout", (event) => {
|
||||
const wrapper = event.target.closest?.(WRAPPER_SELECTOR);
|
||||
if (wrapper && !wrapper.contains(event.relatedTarget) && !wrapper.matches(":hover")) {
|
||||
closeMenu(wrapper);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
const trigger = event.target.closest?.(TRIGGER_SELECTOR);
|
||||
const wrapper = trigger?.closest(WRAPPER_SELECTOR);
|
||||
if (wrapper) {
|
||||
openMenu(wrapper);
|
||||
return;
|
||||
}
|
||||
if (!event.target.closest?.(WRAPPER_SELECTOR)) {
|
||||
document.querySelectorAll(`${WRAPPER_SELECTOR}.is-open`).forEach((openWrapper) => closeMenu(openWrapper));
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (event.key !== "Escape") return;
|
||||
const wrapper = [...document.querySelectorAll(WRAPPER_SELECTOR)].find(isMenuVisible);
|
||||
if (!wrapper) return;
|
||||
const hadFocus = wrapper.contains(document.activeElement);
|
||||
closeMenu(wrapper, { dismiss: true });
|
||||
if (hadFocus) wrapper.querySelector(TRIGGER_SELECTOR)?.focus({ preventScroll: true });
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user