본문으로 이동

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

K Design Media Wiki
편집 요약 없음
태그: 되돌려진 기여
편집 요약 없음
태그: 수동 되돌리기
 
(같은 사용자의 중간 판 2개는 보이지 않습니다)
131번째 줄: 131번째 줄:
   qsa('.kdmw-dept-toolbar').forEach(bar=>{
   qsa('.kdmw-dept-toolbar').forEach(bar=>{
     const chips = qsa('.kdmw-chip', bar);
     const chips = qsa('.kdmw-chip', bar);
  var nextEl = bar.nextElementSibling;
    const grid = bar.nextElementSibling?.classList.contains('kdmw-grid')
var grid = (nextEl && nextEl.classList.contains('kdmw-grid')) ? nextEl : null;
      ? bar.nextElementSibling : null;
     const searchBox = qs('.kdmw-search input', bar.closest('.kdmw-section')||document);
     const searchBox = qs('.kdmw-search input', bar.closest('.kdmw-section')||document);



2025년 10월 27일 (월) 19:22 기준 최신판

/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */
/* 간단한 페이드/슬라이드 쇼 (DHTML) */
mw.loader.using('jquery').then(function () {
  function initSlideshow($root) {
    var interval = Number($root.data('interval')) || 4000;
    var mode = String($root.data('transition') || 'fade').toLowerCase();
    var $rawSlides = $root.find('.slide');

    if (!$rawSlides.length) return;

    // 버튼 & 도트 UI
    var $prev = $('<button class="km-nav km-prev" type="button" aria-label="Previous">‹</button>');
    var $next = $('<button class="km-nav km-next" type="button" aria-label="Next">›</button>');
    var $dots = $('<div class="km-dots" role="tablist"></div>');

    var current = 0, timer = null;

    if (mode === 'slide') {
      // 슬라이드 모드: 트랙을 만들어 좌우로 이동
      var $track = $('<div class="km-track"></div>');
      $root.append($track);

      $rawSlides.each(function () {
        var $wrap = $('<div class="km-slide-item"></div>');
        $(this).appendTo($wrap);
        $track.append($wrap);
      });

      var $items = $track.find('.km-slide-item');

      function go(i) {
        current = (i + $items.length) % $items.length;
        var x = -current * 100;
        $track.css('transform', 'translateX(' + x + '%)');
        updateDots();
      }

      function next() { go(current + 1); }
      function prev() { go(current - 1); }

      // 도트 생성
      $items.each(function (idx) {
        var $d = $('<button class="km-dot" type="button" aria-label="Go to slide '+(idx+1)+'"></button>');
        $d.on('click', function () { go(idx); restart(); });
        $dots.append($d);
      });

      // 오토플레이
      function start() { timer = setInterval(next, interval); }
      function stop() { if (timer) { clearInterval(timer); timer = null; } }
      function restart() { stop(); start(); }
      function updateDots() {
        $dots.children().removeClass('active').eq(current).addClass('active');
      }

      $prev.on('click', function(){ prev(); restart(); });
      $next.on('click', function(){ next(); restart(); });

      $root.append($prev, $next, $dots);
      $root.on('mouseenter', stop).on('mouseleave', start);

      // 초기화
      go(0); start();

    } else {
      // 페이드 모드: 겹쳐놓고 opacity 전환
      var $items = $();
      $rawSlides.each(function () {
        var $wrap = $('<div class="km-slide-item"></div>');
        $(this).appendTo($wrap);
        $root.append($wrap);
        $items = $items.add($wrap);
      });

      function show(i) {
        current = (i + $items.length) % $items.length;
        $items.removeClass('active').eq(current).addClass('active');
        updateDots();
      }
      function next() { show(current + 1); }
      function prev() { show(current - 1); }

      // 도트 생성
      $items.each(function (idx) {
        var $d = $('<button class="km-dot" type="button" aria-label="Go to slide '+(idx+1)+'"></button>');
        $d.on('click', function () { show(idx); restart(); });
        $dots.append($d);
      });

      function start() { timer = setInterval(next, interval); }
      function stop() { if (timer) { clearInterval(timer); timer = null; } }
      function restart() { stop(); start(); }
      function updateDots() {
        $dots.children().removeClass('active').eq(current).addClass('active');
      }

      $prev.on('click', function(){ prev(); restart(); });
      $next.on('click', function(){ next(); restart(); });

      $root.append($prev, $next, $dots);
      $root.on('mouseenter', stop).on('mouseleave', start);

      // 초기화
      show(0); start();
    }
  }

  // 페이지 로드 시 실행 (미리보기/비주얼에디터 적용 포함)
  function boot() {
    $('.km-slideshow').each(function () {
      var $root = $(this);
      if (!$root.data('km-inited')) {
        $root.data('km-inited', true);
        initSlideshow($root);
      }
    });
  }
  mw.hook('wikipage.content').add(boot);
  $(boot);
});




/* ====== 간단 필터링 & 탭 ====== */
(function(){
  function qs(a,b=document){return b.querySelector(a)}
  function qsa(a,b=document){return Array.from(b.querySelectorAll(a))}

  // 태그/전공 필터
  qsa('.kdmw-dept-toolbar').forEach(bar=>{
    const chips = qsa('.kdmw-chip', bar);
    const grid = bar.nextElementSibling?.classList.contains('kdmw-grid')
      ? bar.nextElementSibling : null;
    const searchBox = qs('.kdmw-search input', bar.closest('.kdmw-section')||document);

    function apply(){
      if(!grid) return;
      const active = chips.filter(c=>c.classList.contains('is-active')).map(c=>c.dataset.filter);
      const q = (searchBox?.value||'').trim().toLowerCase();
      let shown = 0;
      qsa('.kdmw-card', grid).forEach(card=>{
        const tags = (card.dataset.tags||'').split('|');
        const dept = (card.dataset.dept||'').toLowerCase();
        const text = (card.innerText||'').toLowerCase();
        const tagHit = active.length===0 || active.some(a=>tags.includes(a));
        const searchHit = q==='' || text.includes(q) || dept.includes(q);
        const show = tagHit && searchHit;
        card.style.display = show ? '' : 'none';
        if(show) shown++;
      });
      const empty = qs('.kdmw-empty', grid.parentElement);
      if(empty) empty.style.display = shown===0 ? '' : 'none';
    }

    chips.forEach(c=>{
      c.addEventListener('click', ()=>{
        c.classList.toggle('is-active');
        apply();
      });
    });
    if(searchBox) searchBox.addEventListener('input', apply);
    apply();
  });

  // 탭 스위치
  qsa('.kdmw-tabs').forEach(tabs=>{
    const tabBtns = qsa('.kdmw-tab', tabs);
    const panels = qsa('.kdmw-panel', tabs.parentElement);
    function show(name){
      tabBtns.forEach(b=>b.classList.toggle('is-active', b.dataset.tab===name));
      panels.forEach(p=>p.style.display = (p.dataset.tab===name)?'':'none');
    }
    const first = tabBtns[0]?.dataset.tab;
    tabBtns.forEach(b=>b.addEventListener('click', ()=>show(b.dataset.tab)));
    if(first) show(first);
  });
})();