다른 명령
편집 요약 없음 |
편집 요약 없음 |
||
| 1번째 줄: | 1번째 줄: | ||
/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */ | /* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */ | ||
/*Autofocus on when clicking search button*/ | |||
(function () { | (function () { | ||
const | const DETAILS = document.getElementById('citizen-search-details'); | ||
const TOGGLE_SEL = '#citizen-search-details > summary.citizen-dropdown-summary'; | const TOGGLE_SEL = '#citizen-search-details > summary.citizen-dropdown-summary'; | ||
const CARD_ID = 'citizen-search__card'; | |||
const INPUT_ID = 'searchInput'; | const INPUT_ID = 'searchInput'; | ||
if (!DETAILS) return; | |||
function | function isVisible(el) { | ||
if (!el) return false; | |||
const | const r = el.getBoundingClientRect(); | ||
return r.width > 0 && r.height > 0; | |||
} | } | ||
function | function focusInput(tag) { | ||
const input = document.getElementById(INPUT_ID); | const input = document.getElementById(INPUT_ID); | ||
if (!input) return false; | |||
if (!isVisible(input)) return false; | |||
// iOS-friendly focus | |||
input.focus({ preventScroll: true }); | |||
input.click(); | |||
return document.activeElement === input; | |||
} | } | ||
function | function focusWhenShown() { | ||
const | const card = document.getElementById(CARD_ID); | ||
const input = document.getElementById(INPUT_ID); | const input = document.getElementById(INPUT_ID); | ||
if (!card || !input) return; | |||
// 1) 이미 보이면 즉시 | |||
if (focusInput('immediate')) return; | |||
// 2) Citizen이 열릴 때 CSS transition/animation 타면 그 끝에서 포커스 | |||
const onDone = () => { | |||
if (focusInput('transitionend')) cleanup(); | |||
}; | |||
const cleanup = () => { | |||
card.removeEventListener('transitionend', onDone, true); | |||
card.removeEventListener('animationend', onDone, true); | |||
clearInterval(poll); | |||
}; | |||
card.addEventListener('transitionend', onDone, true); | |||
card.addEventListener('animationend', onDone, true); | |||
// 3) 그래도 안 잡히면 짧은 폴링 (최대 1초) | |||
const start = Date.now(); | |||
const poll = setInterval(() => { | |||
if (focusInput('poll')) return cleanup(); | |||
if (Date.now() - start > 1000) cleanup(); | |||
}, 50); | |||
} | } | ||
// | // 핵심: "사용자 클릭" 이벤트 안에서 열고, 그 다음 '보이는 순간'에 포커스 | ||
function openAndQueueFocus(e) { | |||
const hit = e.target.closest(TOGGLE_SEL); | |||
if (!hit) return; | |||
// 여기서 preventDefault를 걸면 Citizen 토글 로직이 꼬일 수 있어서 | |||
// 일단은 open만 보장하고, Citizen이 열어주는 흐름도 같이 허용. | |||
if (!DETAILS.open) DETAILS.open = true; | |||
focusWhenShown(); | |||
} | |||
// | // iOS: touchstart가 제일 안정적 | ||
document.addEventListener('touchstart', openAndQueueFocus, { capture: true, passive: true }); | |||
document.addEventListener('click', openAndQueueFocus, true); | |||
})(); | })(); | ||
2026년 1월 17일 (토) 18:59 판
/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */
/*Autofocus on when clicking search button*/
(function () {
const DETAILS = document.getElementById('citizen-search-details');
const TOGGLE_SEL = '#citizen-search-details > summary.citizen-dropdown-summary';
const CARD_ID = 'citizen-search__card';
const INPUT_ID = 'searchInput';
if (!DETAILS) return;
function isVisible(el) {
if (!el) return false;
const r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0;
}
function focusInput(tag) {
const input = document.getElementById(INPUT_ID);
if (!input) return false;
if (!isVisible(input)) return false;
// iOS-friendly focus
input.focus({ preventScroll: true });
input.click();
return document.activeElement === input;
}
function focusWhenShown() {
const card = document.getElementById(CARD_ID);
const input = document.getElementById(INPUT_ID);
if (!card || !input) return;
// 1) 이미 보이면 즉시
if (focusInput('immediate')) return;
// 2) Citizen이 열릴 때 CSS transition/animation 타면 그 끝에서 포커스
const onDone = () => {
if (focusInput('transitionend')) cleanup();
};
const cleanup = () => {
card.removeEventListener('transitionend', onDone, true);
card.removeEventListener('animationend', onDone, true);
clearInterval(poll);
};
card.addEventListener('transitionend', onDone, true);
card.addEventListener('animationend', onDone, true);
// 3) 그래도 안 잡히면 짧은 폴링 (최대 1초)
const start = Date.now();
const poll = setInterval(() => {
if (focusInput('poll')) return cleanup();
if (Date.now() - start > 1000) cleanup();
}, 50);
}
// 핵심: "사용자 클릭" 이벤트 안에서 열고, 그 다음 '보이는 순간'에 포커스
function openAndQueueFocus(e) {
const hit = e.target.closest(TOGGLE_SEL);
if (!hit) return;
// 여기서 preventDefault를 걸면 Citizen 토글 로직이 꼬일 수 있어서
// 일단은 open만 보장하고, Citizen이 열어주는 흐름도 같이 허용.
if (!DETAILS.open) DETAILS.open = true;
focusWhenShown();
}
// iOS: touchstart가 제일 안정적
document.addEventListener('touchstart', openAndQueueFocus, { capture: true, passive: true });
document.addEventListener('click', openAndQueueFocus, true);
})();