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

광주문화예술인문스토리플랫폼
이동: 둘러보기, 검색
72번째 줄: 72번째 줄:
 
     // contenteditable div에서 input 이벤트만 사용해도 충분
 
     // contenteditable div에서 input 이벤트만 사용해도 충분
 
     input.addEventListener('input', debouncedFilter);
 
     input.addEventListener('input', debouncedFilter);
 +
   
 +
   
 +
   
 +
  /* ===== 스토리 목차: 탭 동작(한 번에 하나만 열기) ===== */ 
 +
  var $tables = $content.find('.story-toc-tabs');
 +
 +
  $tables.each(function () {
 +
    var $table = $(this);
 +
    var $tabs = $table.find('.story-tab');
 +
 +
    if (!$tabs.length) return;
 +
 +
    // 탭 라벨 클릭 이벤트: 이벤트 중복 방지 위해 네임스페이스 사용
 +
    $table.off('click.storyTabs').on('click.storyTabs', '.story-tab-label', function (e) {
 +
      e.preventDefault();
 +
      e.stopPropagation();
 +
 +
      var $clickedTab = $(this).closest('.story-tab');
 +
 +
      // 다른 탭 모두 닫기
 +
      $tabs.not($clickedTab).each(function () {
 +
        var $t = $(this);
 +
        if (!$t.hasClass('mw-collapsed')) {
 +
          // mw-collapsible은 mw-collapsed 클래스 토글로 제어 가능
 +
          $t.addClass('mw-collapsed');
 +
          $t.find('.mw-collapsible-content').first().hide();
 +
        }
 +
      });
 +
 +
      // 클릭한 탭 열기
 +
      if ($clickedTab.hasClass('mw-collapsed')) {
 +
        $clickedTab.removeClass('mw-collapsed');
 +
        $clickedTab.find('.mw-collapsible-content').first().show();
 +
      }
 +
    });
 +
 +
    // 초기 상태 보정:
 +
    // 혹시 렌더링 환경에 따라 content가 display:block으로 남아있으면 collapsed면 숨김 처리
 +
    $tabs.each(function () {
 +
      var $t = $(this);
 +
      var $panel = $t.find('.mw-collapsible-content').first();
 +
      if ($t.hasClass('mw-collapsed')) {
 +
        $panel.hide();
 +
      } else {
 +
        $panel.show();
 +
      }
 +
    });
 +
  });   
 
});
 
});

2025년 12월 17일 (수) 17:58 판

/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */
mw.hook('wikipage.content').add(function ($content) {
    // 보기 화면에서만 동작
    if (mw.config.get('wgAction') !== 'view') {
        return;
    }

    var input = document.getElementById('myInput');
    if (!input) {
        return;
    }

    var tbody = document.querySelector('.divTable .tbody');
    if (!tbody) {
        return;
    }

    var rows = tbody.getElementsByClassName('row');
    if (!rows.length) {
        return;
    }

    // 1) 행 텍스트를 미리 대문자로 캐시
    var rowData = [];
    for (var i = 0; i < rows.length; i++) {
        var rowText = rows[i].textContent || rows[i].innerText || '';
        rowData.push({
            row: rows[i],
            textUpper: rowText.toUpperCase()
        });
    }

    // 2) 실제 필터 함수
    function filterEpisodes() {
        var text = input.textContent || input.innerText || '';
        var filter = text.trim().toUpperCase();

        // 검색어가 없으면 전부 보이기
        if (!filter) {
            for (var i = 0; i < rowData.length; i++) {
                rowData[i].row.style.display = '';
            }
            return;
        }

        for (var j = 0; j < rowData.length; j++) {
            if (rowData[j].textUpper.indexOf(filter) > -1) {
                rowData[j].row.style.display = '';
            } else {
                rowData[j].row.style.display = 'none';
            }
        }
    }

    // 3) 디바운스 헬퍼 (delay ms 동안 입력 멈췄을 때만 실행)
    function debounce(fn, delay) {
        var timer = null;
        return function () {
            var context = this;
            var args = arguments;
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(function () {
                fn.apply(context, args);
            }, delay);
        };
    }

    var debouncedFilter = debounce(filterEpisodes, 200); // 0.2초

    // contenteditable div에서 input 이벤트만 사용해도 충분
    input.addEventListener('input', debouncedFilter);
    
    
    
  /* ===== 스토리 목차: 탭 동작(한 번에 하나만 열기) ===== */  
  var $tables = $content.find('.story-toc-tabs');

  $tables.each(function () {
    var $table = $(this);
    var $tabs = $table.find('.story-tab');

    if (!$tabs.length) return;

    // 탭 라벨 클릭 이벤트: 이벤트 중복 방지 위해 네임스페이스 사용
    $table.off('click.storyTabs').on('click.storyTabs', '.story-tab-label', function (e) {
      e.preventDefault();
      e.stopPropagation();

      var $clickedTab = $(this).closest('.story-tab');

      // 다른 탭 모두 닫기
      $tabs.not($clickedTab).each(function () {
        var $t = $(this);
        if (!$t.hasClass('mw-collapsed')) {
          // mw-collapsible은 mw-collapsed 클래스 토글로 제어 가능
          $t.addClass('mw-collapsed');
          $t.find('.mw-collapsible-content').first().hide();
        }
      });

      // 클릭한 탭 열기
      if ($clickedTab.hasClass('mw-collapsed')) {
        $clickedTab.removeClass('mw-collapsed');
        $clickedTab.find('.mw-collapsible-content').first().show();
      }
    });

    // 초기 상태 보정:
    // 혹시 렌더링 환경에 따라 content가 display:block으로 남아있으면 collapsed면 숨김 처리
    $tabs.each(function () {
      var $t = $(this);
      var $panel = $t.find('.mw-collapsible-content').first();
      if ($t.hasClass('mw-collapsed')) {
        $panel.hide();
      } else {
        $panel.show();
      }
    });
  });    
});