打开/关闭菜单
26
6679
46
1.2万
OGAS数据中枢
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

Widget:GameSwitcher:修订间差异

来自OGAS数据中枢
弃权者留言 | 贡献
无编辑摘要
弃权者留言 | 贡献
无编辑摘要
第100行: 第100行:


   var next = new Image();
   var next = new Image();
  next.className = 'gs-hero-next';
   next.onload = function () {
   next.onload = function () {
     heroWrap.appendChild(next);
     heroWrap.style.opacity = '0';
    // 强制浏览器完成一次布局,确保 transition 能触发
    next.offsetWidth;
    next.classList.add('gs-hero-next--in');
 
     setTimeout(function () {
     setTimeout(function () {
       heroImg.src = url;
       heroImg.src = url;
       if (heroWrap.contains(next)) heroWrap.removeChild(next);
       heroWrap.style.opacity = '1';
     }, 420); // 略大于 transition 的 400ms
     }, 300);
   };
   };
 
   next.onerror = function () {};
   next.onerror = function () {
    if (heroWrap.contains(next)) heroWrap.removeChild(next);
  };
 
   next.src = url;
   next.src = url;
}
}

2026年6月20日 (六) 11:02的版本

<script type="text/javascript"> document.addEventListener('DOMContentLoaded', function () {

 var switcher = document.querySelector('.game-switcher');
 if (!switcher) return;
 var heroWrap = document.getElementById('gs-hero-wrap');
 var heroImg = heroWrap ? heroWrap.querySelector('img') : null;
 var loaded = {};
 var prefetching = {};
 var storageKey = 'gs-cache-';
 // ============ 初始化 ============
 var firstBtn = switcher.querySelector('.gs-tab-btn');
 if (firstBtn) {
   firstBtn.classList.add('gs-active');
   firstBtn.setAttribute('aria-selected', 'true');
   if (heroImg && !heroImg.getAttribute('src')) {
     heroImg.src = firstBtn.dataset.hero;
   }
 }
 restoreHash();
 // ============ 点击 ============
 switcher.addEventListener('click', function (e) {
   var btn = e.target.closest('.gs-tab-btn');
   if (btn) activate(btn);
 });
 // ============ 键盘 ============
 switcher.addEventListener('keydown', function (e) {
   var btn = e.target.closest('.gs-tab-btn');
   if (!btn) return;
   if (e.key === 'Enter' || e.key === ' ') {
     e.preventDefault();
     activate(btn);
   }
   if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
     e.preventDefault();
     var btns = Array.from(switcher.querySelectorAll('.gs-tab-btn'));
     var idx = btns.indexOf(btn);
     var next = e.key === 'ArrowRight' ? idx + 1 : idx - 1;
     if (next >= 0 && next < btns.length) btns[next].focus();
   }
 });
 // ============ 悬停预加载 ============
 switcher.addEventListener('mouseenter', function (e) {
   var btn = e.target.closest('.gs-tab-btn');
   if (!btn) return;
   var panelId = btn.dataset.panel;
   var pageName = btn.dataset.page;
   if (pageName && !loaded[panelId] && !prefetching[panelId]) {
     prefetch(panelId, pageName);
   }
 }, true);
 // ============ URL hash ============
 window.addEventListener('hashchange', restoreHash);
 // ============ 激活面板 ============
 function activate(btn) {
   if (btn.classList.contains('gs-active')) return;
   var panelId = btn.dataset.panel;
   var heroSrc = btn.dataset.hero;
   var pageName = btn.dataset.page;
   switchHero(heroSrc);
   switcher.querySelectorAll('.gs-tab-btn').forEach(function (b) {
     b.classList.remove('gs-active');
     b.setAttribute('aria-selected', 'false');
   });
   btn.classList.add('gs-active');
   btn.setAttribute('aria-selected', 'true');
   switcher.querySelectorAll('.gs-content-panel').forEach(function (p) {
     p.classList.remove('gs-active');
   });
   var panel = document.getElementById(panelId);
   if (!panel) {
     panel = document.createElement('div');
     panel.id = panelId;
     panel.className = 'gs-content-panel gs-active';
     switcher.querySelector('.gs-content').appendChild(panel);
     loadContent(panel, panelId, pageName);
   } else {
     panel.classList.add('gs-active');
   }
   setHash(panelId);
   schedulePrefetchOthers();
 }
 // ============ 头图切换 ============

function switchHero(url) {

 if (!heroWrap || !heroImg || !url) return;
 if (heroImg.src === url) return;
 var next = new Image();
 next.onload = function () {
   heroWrap.style.opacity = '0';
   setTimeout(function () {
     heroImg.src = url;
     heroWrap.style.opacity = '1';
   }, 300);
 };
 next.onerror = function () {};
 next.src = url;

}

 // ============ 内容加载 ============
 function loadContent(panel, panelId, pageName) {
   if (loaded[panelId]) { panel.innerHTML = loaded[panelId]; return; }
   try {
     var stored = localStorage.getItem(storageKey + panelId);
     if (stored) { loaded[panelId] = stored; panel.innerHTML = stored; return; }
   } catch (e) {}
   if (!pageName) return;

panel.innerHTML = '

加载中...

';

   fetchPage(pageName).then(function (html) {
     loaded[panelId] = html;
     try { localStorage.setItem(storageKey + panelId, html); } catch (e) {}
     panel.innerHTML = html;
   }).catch(function () {

panel.innerHTML = '

加载失败,<a href="javascript:location.reload()">刷新</a>重试

';

   });
 }
 // ============ 预加载 ============
 function prefetch(panelId, pageName) {
   prefetching[panelId] = true;
   try {
     var stored = localStorage.getItem(storageKey + panelId);
     if (stored) { loaded[panelId] = stored; prefetching[panelId] = false; return; }
   } catch (e) {}
   fetchPage(pageName).then(function (html) {
     loaded[panelId] = html;
     try { localStorage.setItem(storageKey + panelId, html); } catch (e) {}
   }).finally(function () {
     prefetching[panelId] = false;
   });
 }
 function schedulePrefetchOthers() {
   setTimeout(function () {
     switcher.querySelectorAll('.gs-tab-btn').forEach(function (btn) {
       var panelId = btn.dataset.panel;
       var pageName = btn.dataset.page;
       if (!loaded[panelId] && !prefetching[panelId] && pageName) {
         prefetch(panelId, pageName);
       }
     });
   }, 500);
 }
 // ============ API 请求 ============
 function fetchPage(pageName) {
   var url = mw.util.wikiScript('api') +
     '?action=parse&page=' + encodeURIComponent(pageName) +
     '&prop=text&format=json&disablelimitreport=1&origin=*';
   return fetch(url)
     .then(function (r) { return r.json(); })
     .then(function (data) {
       if (data.parse && data.parse.text) return data.parse.text['*'];
       throw new Error('empty');
     });
 }
 // ============ URL hash ============
 function setHash(panelId) {
   try { history.replaceState(null, , '#' + panelId); } catch (e) {}
 }
 function restoreHash() {
   var hash = location.hash.replace('#', );
   if (hash && hash.indexOf('panel-') === 0) {
     var btn = switcher.querySelector('[data-panel="' + hash + '"]');
     if (btn && !btn.classList.contains('gs-active')) activate(btn);
   }
 }

}); </script>