메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

미디어위키:Common.js: 두 판 사이의 차이

novawiki
편집 요약 없음
편집 요약 없음
5번째 줄: 5번째 줄:
  * Triggered when MobileFrontend search UI opens
  * Triggered when MobileFrontend search UI opens
  * Improves UX by immediately opening the virtual keyboard
  * Improves UX by immediately opening the virtual keyboard
*/
/**
* iOS-friendly autofocus for Citizen search
* - Bind focus to the actual user gesture on the search toggle (summary)
* - Use a couple rAFs to wait for the input to appear/expand
  */
  */
(function () {
(function () {
   function focusSearchInput() {
   const TOGGLE_SELECTOR = '#citizen-search-details > summary.citizen-dropdown-summary';
    const input =
  const INPUT_SELECTOR = '#searchInput';
      document.querySelector('.citizen-search__input') ||
      document.querySelector('#searchInput') ||
      document.querySelector('input[type="search"]');


  function focusInput() {
    const input = document.querySelector(INPUT_SELECTOR);
     if (!input) return false;
     if (!input) return false;


     // iOS는 visible/enable 상태 아니면 focus 무시하는 경우 많음
     // If the toggle is still animating / collapsing, focus may fail.
    // preventScroll avoids weird jump on mobile.
     input.focus({ preventScroll: true });
     input.focus({ preventScroll: true });


     // 어떤 iOS 버전/스킨 조합에서는 click이 키보드 트리거에 도움됨
     // Some iOS versions are picky; a click can help trigger the keyboard.
    // (Harmless elsewhere.)
     input.click();
     input.click();


24번째 줄: 31번째 줄:
   }
   }


   // "유저 제스처"로 인정받기 좋은 이벤트들
  function focusSoon() {
   const EVENTS = ['touchend', 'pointerup', 'mouseup', 'click'];
    // Try immediately first (best chance to count as user gesture)
    if (focusInput()) return;
 
    // Then wait 1-2 frames for Citizen to render/open the search card
    requestAnimationFrame(() => {
      if (focusInput()) return;
      requestAnimationFrame(() => focusInput());
    });
  }
 
   // Use capturing so we still get it even if other handlers stop propagation.
   document.addEventListener(
    'touchend',
    function (e) {
      if (e.target.closest(TOGGLE_SELECTOR)) focusSoon();
    },
    true
  );
 
  // Fallback for devices/browsers that don't fire touchend as expected
  document.addEventListener(
    'click',
    function (e) {
      if (e.target.closest(TOGGLE_SELECTOR)) focusSoon();
    },
    true
  );
})();
 
/*general*/


  EVENTS.forEach((evt) => {
(function () {
     document.addEventListener(
    function focusSearch() {
      evt,
        const input =
      function (e) {
            document.querySelector('.citizen-search__input') ||
         // 검색 버튼/아이콘 후보들(필요하면 여기 셀렉터만 너 환경에 맞게 좁히면 됨)
            document.querySelector('#searchInput') ||
         const isSearchButton = e.target.closest(
            document.querySelector('input[type="search"]');
          '.citizen-search__button, .mw-ui-icon-search, .search-toggle, a[title="Search"], button[title="Search"]'
 
        );
        if (input) {
            input.focus({ preventScroll: true });
            input.click();
        }
    }
 
    // 검색 버튼/아이콘(스킨마다 다름)에서 이벤트로 잡기
     document.addEventListener('click', function (e) {
         // Citizen/모바일에서 검색 토글 버튼 후보들
         const isSearchButton =
            e.target.closest('.citizen-search__button, .mw-ui-icon-search, .search-toggle, a[title="Search"], button[title="Search"]');


         if (!isSearchButton) return;
         if (!isSearchButton) return;


         // 1) 즉시 시도 (가장 iOS 친화적)
         // 버튼 누른 "직후" 입력창이 생기므로 프레임 2번 정도만 양보
        if (focusSearchInput()) return;
         requestAnimationFrame(() => requestAnimationFrame(focusSearch));
 
    }, true);
        // 2) UI가 한 프레임 늦게 뜨면 1~2 프레임 양보
         requestAnimationFrame(() => {
          if (focusSearchInput()) return;
          requestAnimationFrame(() => focusSearchInput());
        });
      },
      true // 캡처링: 스킨/확장이 stopPropagation 해도 이쪽이 먼저 받을 확률 ↑
    );
  });
})();
})();

2026년 1월 17일 (토) 18:45 판

/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */

/**
 * Autofocus search input on mobile
 * Triggered when MobileFrontend search UI opens
 * Improves UX by immediately opening the virtual keyboard
 */

/**
 * iOS-friendly autofocus for Citizen search
 * - Bind focus to the actual user gesture on the search toggle (summary)
 * - Use a couple rAFs to wait for the input to appear/expand
 */
(function () {
  const TOGGLE_SELECTOR = '#citizen-search-details > summary.citizen-dropdown-summary';
  const INPUT_SELECTOR = '#searchInput';

  function focusInput() {
    const input = document.querySelector(INPUT_SELECTOR);
    if (!input) return false;

    // If the toggle is still animating / collapsing, focus may fail.
    // preventScroll avoids weird jump on mobile.
    input.focus({ preventScroll: true });

    // Some iOS versions are picky; a click can help trigger the keyboard.
    // (Harmless elsewhere.)
    input.click();

    return document.activeElement === input;
  }

  function focusSoon() {
    // Try immediately first (best chance to count as user gesture)
    if (focusInput()) return;

    // Then wait 1-2 frames for Citizen to render/open the search card
    requestAnimationFrame(() => {
      if (focusInput()) return;
      requestAnimationFrame(() => focusInput());
    });
  }

  // Use capturing so we still get it even if other handlers stop propagation.
  document.addEventListener(
    'touchend',
    function (e) {
      if (e.target.closest(TOGGLE_SELECTOR)) focusSoon();
    },
    true
  );

  // Fallback for devices/browsers that don't fire touchend as expected
  document.addEventListener(
    'click',
    function (e) {
      if (e.target.closest(TOGGLE_SELECTOR)) focusSoon();
    },
    true
  );
})();

/*general*/

(function () {
    function focusSearch() {
        const input =
            document.querySelector('.citizen-search__input') ||
            document.querySelector('#searchInput') ||
            document.querySelector('input[type="search"]');

        if (input) {
            input.focus({ preventScroll: true });
            input.click();
        }
    }

    // 검색 버튼/아이콘(스킨마다 다름)에서 이벤트로 잡기
    document.addEventListener('click', function (e) {
        // Citizen/모바일에서 검색 토글 버튼 후보들
        const isSearchButton =
            e.target.closest('.citizen-search__button, .mw-ui-icon-search, .search-toggle, a[title="Search"], button[title="Search"]');

        if (!isSearchButton) return;

        // 버튼 누른 "직후" 입력창이 생기므로 프레임 2번 정도만 양보
        requestAnimationFrame(() => requestAnimationFrame(focusSearch));
    }, true);
})();