Widget:GameSwitcher:修订间差异
来自OGAS数据中枢
更多操作
无编辑摘要 |
无编辑摘要 |
||
| 第13行: | 第13行: | ||
}; | }; | ||
function | function getApiBase() { | ||
var canonical = document.querySelector( 'link[rel="canonical"]' ); | var canonical = document.querySelector( 'link[rel="canonical"]' ); | ||
if ( canonical ) { | if ( canonical ) { | ||
var match = canonical.href.match( /^(https?:\/\/[^\/]+(?:\/[^\/]+)*?)\/wiki\// ); | var match = canonical.href.match( /^(https?:\/\/[^\/]+(?:\/[^\/]+)*?)\/wiki\// ); | ||
if ( match ) { | if ( match ) { return match[ 1 ] + '/api.php'; } | ||
} | } | ||
return window.location.origin + '/api.php'; | |||
} | |||
fetch( | function getWikiImageUrl( filename, callback ) { | ||
fetch( getApiBase() + '?action=query&titles=File:' + encodeURIComponent( filename ) + | |||
'&prop=imageinfo&iiprop=url&format=json&origin=*' ) | '&prop=imageinfo&iiprop=url&format=json&origin=*' ) | ||
.then( function ( r ) { return r.json(); } ) | .then( function ( r ) { return r.json(); } ) | ||
| 第37行: | 第33行: | ||
} | } | ||
} ) | } ) | ||
.catch( function ( e ) { console.warn( ' | .catch( function ( e ) { console.warn( 'GameSwitcher: 图片加载失败', filename, e ); } ); | ||
} | } | ||
| 第55行: | 第51行: | ||
} ); | } ); | ||
} | } | ||
/* 当前正在显示的游戏,用于防止动画中途重复触发 */ | |||
var currentGame = 'gf'; | |||
var switching = false; | |||
function switchGame( game ) { | function switchGame( game ) { | ||
document.querySelectorAll( '#gf-homepage .gf-tab' ).forEach( function ( t ) { | if ( game === currentGame || switching ) { return; } | ||
switching = true; | |||
var slides = document.querySelectorAll( '#gf-homepage .gf-hero-slide' ); | |||
var panels = document.querySelectorAll( '#gf-homepage .gf-content-panel' ); | |||
var tabs = document.querySelectorAll( '#gf-homepage .gf-tab' ); | |||
var outSlide = document.getElementById( 'hero-' + currentGame ); | |||
var inSlide = document.getElementById( 'hero-' + game ); | |||
/* 新图先置于底层不透明度0,再淡入;旧图同时淡出 */ | |||
if ( inSlide ) { | |||
inSlide.style.zIndex = '1'; | |||
inSlide.style.opacity = '0'; | |||
inSlide.style.transition = 'opacity 0.5s ease'; | |||
/* 强制reflow让transition生效 */ | |||
void inSlide.offsetWidth; | |||
inSlide.style.opacity = '1'; | |||
} | |||
if ( outSlide ) { | |||
outSlide.style.zIndex = '0'; | |||
outSlide.style.opacity = '1'; | |||
outSlide.style.transition = 'opacity 0.5s ease'; | |||
void outSlide.offsetWidth; | |||
outSlide.style.opacity = '0'; | |||
} | |||
/* 内容面板切换 */ | |||
panels.forEach( function ( p ) { | |||
p.classList.toggle( 'active', p.id === 'content-' + game ); | |||
} ); | |||
/* tab状态 */ | |||
tabs.forEach( function ( t ) { | |||
var on = t.getAttribute( 'data-game' ) === game; | var on = t.getAttribute( 'data-game' ) === game; | ||
t.classList.toggle( 'active', on ); | t.classList.toggle( 'active', on ); | ||
t.setAttribute( 'aria-selected', on ? 'true' : 'false' ); | t.setAttribute( 'aria-selected', on ? 'true' : 'false' ); | ||
} ); | } ); | ||
/* 动画结束后清理zIndex,解除锁定 */ | |||
setTimeout( function () { | |||
slides.forEach( function ( s ) { | |||
s.style.zIndex = ''; | |||
} ); | s.style.opacity = s.id === 'hero-' + game ? '1' : '0'; | ||
s.style.transition = ''; | |||
} ); | |||
currentGame = game; | |||
switching = false; | |||
}, 520 ); | |||
} | } | ||
| 第74行: | 第112行: | ||
if ( !tabs.length ) { return; } | if ( !tabs.length ) { return; } | ||
/* 预加载并注入背景图 */ | |||
Object.keys( heroImages ).forEach( function ( game ) { | Object.keys( heroImages ).forEach( function ( game ) { | ||
getWikiImageUrl( heroImages[ game ], function ( url ) { | getWikiImageUrl( heroImages[ game ], function ( url ) { | ||
2026年6月20日 (六) 17:10的版本
本Widget为少女前线系列多游戏首页提供切换交互逻辑。
不接受参数,直接在首页调用:{{#widget:GFHomepageSwitcher}}