卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
MediaWiki
查看“︁Common.js”︁的源代码
←
MediaWiki:Common.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */ /* 切换标签 */ (function() { 'use strict'; function initTabSwitcher() { var tabContainers = document.querySelectorAll('.resp-tabs'); tabContainers.forEach(function(container) { var tabButtons = container.querySelectorAll('.czn-list-style'); if (tabButtons.length === 0) return; var tabContents = container.querySelectorAll('.resp-tab-content'); // 初始化 tabButtons.forEach(function(button, index) { button.classList.toggle('active', index === 0); }); if (tabContents.length > 0) { tabContents.forEach(function(content, index) { content.style.display = index === 0 ? 'block' : 'none'; }); } // 点击事件 tabButtons.forEach(function(button, index) { button.addEventListener('click', function(e) { e.preventDefault(); // 更新标签状态 tabButtons.forEach(function(btn, i) { btn.classList.toggle('active', i === index); }); // 切换内容 if (tabContents.length > 0) { tabContents.forEach(function(content, i) { content.style.display = i === index ? 'block' : 'none'; }); } }); }); }); } // 初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initTabSwitcher); } else { initTabSwitcher(); } })(); /* 战斗员筛选 */ $(function() { // 初始化筛选系统 function initFilterSystem() { // 清理数据并设置属性 $('.战斗员卡片').each(function() { var $card = $(this); var rarity = ($card.attr('data-rarity') || '').trim(); var profession = ($card.attr('data-profession') || '').trim(); var attribute = ($card.attr('data-attribute') || '').trim(); $card.attr({ 'data-rarity': rarity, 'data-profession': profession, 'data-attribute': attribute }); }); // 存储当前筛选状态 var activeFilters = {}; // 筛选按钮点击事件 $('.filter-button').off('click').on('click', function(e) { e.preventDefault(); var $button = $(this); var group = String($button.data('filter-group')); var value = String($button.data('filter-value')).trim(); // 切换按钮状态 if (group === '0' && value === '0') { // 查看全部按钮 $('.filter-button').removeClass('active'); $button.addClass('active'); activeFilters = {}; } else { // 其他筛选按钮 $('.filter-button[data-filter-group="0"]').removeClass('active'); // 同组内只能选择一个 $('.filter-button[data-filter-group="' + group + '"]').removeClass('active'); if (activeFilters[group] === value) { // 如果点击已激活的按钮,则取消选择 delete activeFilters[group]; $button.removeClass('active'); } else { // 激活新的筛选 $button.addClass('active'); activeFilters[group] = value; } // 如果没有任何筛选项,激活"查看全部" if (Object.keys(activeFilters).length === 0) { $('.filter-button[data-filter-group="0"][data-filter-value="0"]').addClass('active'); } } // 应用筛选 applyFilters(); }); // 应用筛选函数 function applyFilters() { $('.战斗员卡片').each(function() { var $card = $(this); var shouldShow = true; // 检查每个激活的筛选条件 for (var group in activeFilters) { var filterValue = String(activeFilters[group]).trim(); var cardValue = ''; // 根据组号获取对应的卡片属性 switch(group) { case '1': // 稀有度 cardValue = String($card.attr('data-rarity') || '').trim(); break; case '2': // 职业 cardValue = String($card.attr('data-profession') || '').trim(); break; case '3': // 属性 cardValue = String($card.attr('data-attribute') || '').trim(); break; default: cardValue = String($card.attr('data-filter-' + group) || '').trim(); } if (cardValue !== filterValue) { shouldShow = false; break; } } // 显示或隐藏卡片 if (shouldShow) { $card.fadeIn(200); } else { $card.fadeOut(200); } }); // 更新显示数量 updateCount(); } // 更新显示数量 function updateCount() { var visibleCount = $('.战斗员卡片:visible').length; var totalCount = $('.战斗员卡片').length; if ($('#filter-count').length === 0) { $('.filter-container').prepend('<div id="filter-count"></div>'); } $('#filter-count').text('显示 ' + visibleCount + ' / ' + totalCount + ' 个战斗员'); } // 初始化筛选按钮的data属性(清理空格) $('.filter-button').each(function() { var $button = $(this); var value = String($button.data('filter-value') || '').trim(); $button.attr('data-filter-value', value); }); // 初始化时激活"查看全部"按钮 $('.filter-button[data-filter-group="0"][data-filter-value="0"]').addClass('active'); updateCount(); } // 等待页面加载完成 var checkInterval = setInterval(function() { if ($('.战斗员卡片').length > 0 && $('.filter-button').length > 0) { clearInterval(checkInterval); initFilterSystem(); } }, 500); // 10秒后停止检查 setTimeout(function() { clearInterval(checkInterval); }, 10000); }); /* 卡牌 */ (function() { 'use strict'; // 防止重复初始化 if (window.cardSystemInitialized) return; window.cardSystemInitialized = true; // ========== 配置和缓存 ========== const CONFIG = { CACHE_EXPIRY: 1800000, // 30分钟缓存 PRELOAD_DELAY: 100, // 预加载延迟 MAX_CONCURRENT: 3 // 最大并发请求数 }; // 内存缓存 const memoryCache = new Map(); // LocalStorage缓存管理 const StorageCache = { set: function(key, data) { try { const item = { data: data, timestamp: Date.now() }; localStorage.setItem('card_' + key, JSON.stringify(item)); } catch(e) { console.warn('localStorage写入失败:', e); } }, get: function(key) { try { const item = localStorage.getItem('card_' + key); if (!item) return null; const parsed = JSON.parse(item); if (Date.now() - parsed.timestamp > CONFIG.CACHE_EXPIRY) { localStorage.removeItem('card_' + key); return null; } return parsed.data; } catch(e) { return null; } }, clear: function() { try { const keys = Object.keys(localStorage); keys.forEach(key => { if (key.startsWith('card_')) { localStorage.removeItem(key); } }); } catch(e) {} } }; // ========== DOM缓存 ========== let overlayCache = null; let containerCache = null; let currentCardInfo = null; // ========== 请求队列管理 ========== const RequestQueue = { queue: [], active: 0, add: function(fn) { return new Promise((resolve, reject) => { this.queue.push({ fn, resolve, reject }); this.process(); }); }, process: function() { while (this.active < CONFIG.MAX_CONCURRENT && this.queue.length > 0) { const { fn, resolve, reject } = this.queue.shift(); this.active++; fn().then(resolve).catch(reject).finally(() => { this.active--; this.process(); }); } } }; // ========== API调用优化 ========== function fetchCardHTML(character, cardName, deckType) { const cacheKey = `${character}|${cardName}|${deckType || ''}`; // 检查内存缓存 if (memoryCache.has(cacheKey)) { return Promise.resolve(memoryCache.get(cacheKey)); } // 检查localStorage缓存 const cached = StorageCache.get(cacheKey); if (cached) { memoryCache.set(cacheKey, cached); return Promise.resolve(cached); } // 加入请求队列 return RequestQueue.add(() => { return new Promise((resolve, reject) => { const api = new mw.Api(); const wikitext = `{{#invoke:卡牌|main|${character}|${cardName}|${deckType || ''}}}`; api.parse(wikitext).done(html => { // 双重缓存 memoryCache.set(cacheKey, html); StorageCache.set(cacheKey, html); resolve(html); }).fail(err => { console.error('API调用失败:', err); resolve('<div style="color: white;">加载失败</div>'); }); }); }); } // ========== 预加载机制 ========== function preloadCards() { const cards = document.querySelectorAll('.game-card'); const toPreload = []; cards.forEach(card => { const character = card.dataset.character; const cardName = card.dataset.cardName; const derivedCards = card.dataset.derivedCards; if (character && cardName) { // 预加载变体 toPreload.push({ character, cardName, deckType: '灵光一闪' }); toPreload.push({ character, cardName, deckType: '神之一闪' }); // 预加载衍生卡牌 if (derivedCards) { derivedCards.split('、').forEach(derived => { toPreload.push({ character, cardName: derived.trim(), deckType: '' }); }); } } }); // 延迟预加载,不阻塞主线程 setTimeout(() => { toPreload.forEach((item, index) => { setTimeout(() => { fetchCardHTML(item.character, item.cardName, item.deckType); }, index * CONFIG.PRELOAD_DELAY); }); }, 1000); } // ========== UI组件 ========== function createOverlay() { if (overlayCache && containerCache) { return { overlay: overlayCache, container: containerCache }; } const overlay = document.createElement('div'); overlay.id = 'card-overlay'; overlay.style.cssText = 'display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 9999; overflow-y: auto;'; const container = document.createElement('div'); container.id = 'card-display-container'; container.style.cssText = 'position: relative; min-height: 100vh; padding: 40px 20px; display: flex; align-items: center; justify-content: center;'; overlay.appendChild(container); document.body.appendChild(overlay); overlay.addEventListener('click', e => { if (e.target === overlay) closeCardDisplay(); }); overlayCache = overlay; containerCache = container; return { overlay, container }; } function createLoadingSpinner() { const spinner = document.createElement('div'); spinner.style.cssText = 'color: white; font-size: 18px; text-align: center;'; spinner.innerHTML = ` <div style="display: inline-block; width: 50px; height: 50px; border: 3px solid rgba(255,255,255,.3); border-radius: 50%; border-top-color: white; animation: spin 1s ease-in-out infinite;"></div> <div style="margin-top: 10px;">加载中...</div> `; // 添加旋转动画 if (!document.getElementById('card-spinner-style')) { const style = document.createElement('style'); style.id = 'card-spinner-style'; style.textContent = '@keyframes spin { to { transform: rotate(360deg); } }'; document.head.appendChild(style); } return spinner; } function createCloseButton() { const btn = document.createElement('div'); btn.style.cssText = 'position: fixed; top: 20px; right: 20px; width: 40px; height: 40px; background: rgba(255,255,255,0.1); border: 2px solid white; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 10001; transition: all 0.3s;'; btn.innerHTML = '<span style="color: white; font-size: 24px; font-weight: bold;">×</span>'; btn.onmouseover = () => { btn.style.background = 'rgba(255,255,255,0.2)'; btn.style.transform = 'scale(1.1)'; }; btn.onmouseout = () => { btn.style.background = 'rgba(255,255,255,0.1)'; btn.style.transform = 'scale(1)'; }; btn.onclick = closeCardDisplay; return btn; } function createBackButton(onClick) { const btn = document.createElement('div'); btn.style.cssText = 'position: fixed; top: 20px; left: 20px; padding: 10px 20px; background: linear-gradient(135deg, #4a90e2, #357abd); color: white; border-radius: 6px; cursor: pointer; font-weight: bold; box-shadow: 0 2px 8px rgba(0,0,0,0.3); z-index: 10001; transition: transform 0.2s;'; btn.textContent = '← 返回'; btn.onmouseover = () => btn.style.transform = 'scale(1.05)'; btn.onmouseout = () => btn.style.transform = 'scale(1)'; btn.onclick = onClick; return btn; } function closeCardDisplay() { if (overlayCache) { overlayCache.style.display = 'none'; if (containerCache) containerCache.innerHTML = ''; } currentCardInfo = null; } // ========== 卡牌展示 ========== async function showEnlargedCard(cardElement) { const { overlay, container } = createOverlay(); const cardName = cardElement.dataset.cardName; const character = cardElement.dataset.character; const deckType = cardElement.dataset.deckType; const derivedCards = cardElement.dataset.derivedCards; currentCardInfo = { element: cardElement, cardName, character, deckType, derivedCards }; // 显示加载动画 container.innerHTML = ''; container.appendChild(createLoadingSpinner()); overlay.style.display = 'block'; // 使用DocumentFragment减少DOM操作 const fragment = document.createDocumentFragment(); const contentWrapper = document.createElement('div'); contentWrapper.style.cssText = 'display: flex; align-items: center; gap: 0px; position: relative;'; // 并行加载衍生卡牌和变体检查 const promises = []; // 处理衍生卡牌 if (derivedCards && derivedCards.trim()) { const derivedList = derivedCards.split('、'); const leftContainer = document.createElement('div'); leftContainer.style.cssText = 'display: flex; flex-direction: column; gap: 20px; align-items: center;'; const derivedWrapper = document.createElement('div'); derivedWrapper.style.cssText = 'width: 252px; height: 345px; display: flex; align-items: center; justify-content: center;'; const firstDerived = document.createElement('div'); firstDerived.style.cssText = 'transform: scale(1.5); transform-origin: center center;'; promises.push( fetchCardHTML(character, derivedList[0].trim(), '').then(html => { firstDerived.innerHTML = html; attachCardClickEvents(firstDerived); }) ); derivedWrapper.appendChild(firstDerived); leftContainer.appendChild(derivedWrapper); if (derivedList.length > 1) { const viewAllBtn = createButton('查看所有衍生卡牌', () => { showAllDerivedCards(character, derivedList); }); leftContainer.appendChild(viewAllBtn); } contentWrapper.appendChild(leftContainer); } // 主卡牌容器 const rightContainer = document.createElement('div'); rightContainer.style.cssText = 'display: flex; flex-direction: column; align-items: center; gap: 30px;'; const mainCardContainer = document.createElement('div'); mainCardContainer.style.cssText = 'width: 336px; height: 460px; display: flex; align-items: center; justify-content: center;'; const cardInner = document.createElement('div'); cardInner.style.cssText = 'transform: scale(2); position: relative;'; const enlargedCard = cardElement.cloneNode(true); enlargedCard.style.cssText = 'width: 168px; height: 230px; cursor: default; position: relative; display: block;'; enlargedCard.onclick = null; cardInner.appendChild(enlargedCard); mainCardContainer.appendChild(cardInner); rightContainer.appendChild(mainCardContainer); // 检查变体 const buttonsContainer = document.createElement('div'); buttonsContainer.style.cssText = 'display: flex; gap: 15px;'; promises.push( checkCardVariants(character, cardName).then(variants => { if (variants.lingguang) { const btn = createVariantButton('灵光一闪', '#667eea', '#764ba2', () => { showVariantCards(character, cardName, '灵光一闪'); }); buttonsContainer.appendChild(btn); } if (variants.shenguang) { const btn = createVariantButton('神之一闪', '#f093fb', '#f5576c', () => { showVariantCards(character, cardName, '神之一闪'); }); buttonsContainer.appendChild(btn); } }) ); // 等待所有异步操作完成 await Promise.all(promises); if (buttonsContainer.children.length > 0) { rightContainer.appendChild(buttonsContainer); } contentWrapper.appendChild(rightContainer); fragment.appendChild(contentWrapper); fragment.appendChild(createCloseButton()); // 一次性更新DOM container.innerHTML = ''; container.appendChild(fragment); } function createButton(text, onClick) { const btn = document.createElement('div'); btn.style.cssText = 'padding: 10px 20px; background: linear-gradient(135deg, #4a90e2, #357abd); color: white; border-radius: 6px; cursor: pointer; white-space: nowrap; font-weight: bold; box-shadow: 0 2px 8px rgba(0,0,0,0.3); transition: transform 0.2s;'; btn.textContent = text; btn.onmouseover = () => btn.style.transform = 'scale(1.05)'; btn.onmouseout = () => btn.style.transform = 'scale(1)'; btn.onclick = onClick; return btn; } function createVariantButton(text, color1, color2, onClick) { const btn = document.createElement('div'); btn.style.cssText = `padding: 10px 30px; background: linear-gradient(135deg, ${color1} 0%, ${color2} 100%); color: white; border-radius: 6px; cursor: pointer; font-weight: bold; box-shadow: 0 2px 8px rgba(0,0,0,0.3); transition: transform 0.2s; white-space: nowrap; min-width: 120px; text-align: center;`; btn.textContent = text; btn.onmouseover = () => btn.style.transform = 'scale(1.05)'; btn.onmouseout = () => btn.style.transform = 'scale(1)'; btn.onclick = onClick; return btn; } // ========== 衍生卡牌展示 ========== async function showAllDerivedCards(character, derivedCardsList) { const { overlay, container } = createOverlay(); // 显示加载 container.innerHTML = ''; container.appendChild(createLoadingSpinner()); overlay.style.display = 'block'; const fragment = document.createDocumentFragment(); // 标题 const title = document.createElement('div'); title.style.cssText = 'color: white; font-size: 28px; font-weight: bold; margin-bottom: 30px; text-align: center;'; title.textContent = '衍生卡牌'; fragment.appendChild(title); // 卡牌容器 const cardsContainer = document.createElement('div'); cardsContainer.style.cssText = 'display: flex; flex-wrap: wrap; gap: 30px; justify-content: center; max-width: 1400px; transform: scale(1.5); transform-origin: center center; padding: 40px;'; // 去重并并行加载 const uniqueCards = [...new Set(derivedCardsList.map(name => name.trim()))]; const loadPromises = uniqueCards.map(cardName => fetchCardHTML(character, cardName, '').then(html => ({ cardName, html })) ); const results = await Promise.all(loadPromises); // 批量创建DOM results.forEach(({ cardName, html }) => { const cardWrapper = document.createElement('div'); cardWrapper.innerHTML = html; const cards = cardWrapper.querySelectorAll('.game-card'); cards.forEach(card => { const derivedCards = card.dataset.derivedCards; if (derivedCards && derivedCards.trim()) { // 有衍生卡牌的卡片需要按钮 const buttonContainer = document.createElement('div'); buttonContainer.style.cssText = 'display: flex; flex-direction: column; align-items: center; gap: 10px;'; const cardContainer = document.createElement('div'); const clonedCard = card.cloneNode(true); clonedCard.style.cursor = 'pointer'; clonedCard.onclick = e => { e.stopPropagation(); showEnlargedCard(clonedCard); }; cardContainer.appendChild(clonedCard); buttonContainer.appendChild(cardContainer); const viewBtn = document.createElement('div'); viewBtn.style.cssText = 'padding: 8px 15px; background: linear-gradient(135deg, #4a90e2, #357abd); color: white; border-radius: 6px; cursor: pointer; white-space: nowrap; font-weight: bold; box-shadow: 0 2px 8px rgba(0,0,0,0.3); transition: transform 0.2s; font-size: 12px;'; viewBtn.textContent = '查看衍生卡牌'; viewBtn.onmouseover = () => viewBtn.style.transform = 'scale(1.05)'; viewBtn.onmouseout = () => viewBtn.style.transform = 'scale(1)'; viewBtn.onclick = e => { e.stopPropagation(); showAllDerivedCards(character, derivedCards.split('、')); }; buttonContainer.appendChild(viewBtn); cardsContainer.appendChild(buttonContainer); } else { // 普通卡片 card.style.cursor = 'pointer'; card.onclick = e => { e.stopPropagation(); showEnlargedCard(card); }; cardsContainer.appendChild(card); } }); }); fragment.appendChild(cardsContainer); fragment.appendChild(createBackButton(() => { if (currentCardInfo && currentCardInfo.element) { showEnlargedCard(currentCardInfo.element); } })); fragment.appendChild(createCloseButton()); container.innerHTML = ''; container.appendChild(fragment); } // ========== 变体卡牌展示 ========== async function showVariantCards(character, cardName, variantType) { const { overlay, container } = createOverlay(); // 显示加载 container.innerHTML = ''; container.appendChild(createLoadingSpinner()); overlay.style.display = 'block'; const fragment = document.createDocumentFragment(); // 标题 const title = document.createElement('div'); title.style.cssText = 'color: white; font-size: 28px; font-weight: bold; margin-bottom: 30px; text-align: center; background: linear-gradient(135deg, #667eea, #764ba2); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;'; title.textContent = `${cardName} - ${variantType}`; fragment.appendChild(title); // 卡牌容器 const cardsContainer = document.createElement('div'); cardsContainer.style.cssText = 'display: flex; flex-wrap: nowrap; gap: 30px; justify-content: center; max-width: 1400px; overflow-x: auto; padding: 40px; transform: scale(1.5); transform-origin: center center;'; // 加载变体卡牌 const html = await fetchCardHTML(character, cardName, variantType); cardsContainer.innerHTML = html; // 移除点击事件 const cards = cardsContainer.querySelectorAll('.game-card'); cards.forEach(card => { card.style.cursor = 'default'; card.style.flexShrink = '0'; card.onclick = null; }); fragment.appendChild(cardsContainer); fragment.appendChild(createBackButton(() => { if (currentCardInfo && currentCardInfo.element) { showEnlargedCard(currentCardInfo.element); } })); fragment.appendChild(createCloseButton()); container.innerHTML = ''; container.appendChild(fragment); } // ========== 变体检查 ========== function checkCardVariants(character, cardName) { return Promise.all([ fetchCardHTML(character, cardName, '灵光一闪'), fetchCardHTML(character, cardName, '神之一闪') ]).then(([lingguangHtml, shenguangHtml]) => ({ lingguang: lingguangHtml && !lingguangHtml.includes('找不到卡组'), shenguang: shenguangHtml && !shenguangHtml.includes('找不到卡组') })); } // ========== 事件绑定工具 ========== function attachCardClickEvents(container) { const cards = container.querySelectorAll('.game-card'); cards.forEach(card => { card.style.cursor = 'pointer'; card.onclick = e => { e.stopPropagation(); showEnlargedCard(card); }; }); } // ========== 初始化 ========== function init() { // 使用事件委托优化性能 document.addEventListener('click', e => { const card = e.target.closest('.game-card'); if (card && !card.closest('#card-overlay')) { e.preventDefault(); e.stopPropagation(); showEnlargedCard(card); } }, true); // 延迟预加载,避免阻塞页面加载 if (document.readyState === 'complete') { setTimeout(preloadCards, 2000); } else { window.addEventListener('load', () => { setTimeout(preloadCards, 2000); }); } // 定期清理过期缓存 setInterval(() => { const now = Date.now(); memoryCache.forEach((value, key) => { // 清理超过30分钟的内存缓存 if (now - (value.timestamp || 0) > CONFIG.CACHE_EXPIRY) { memoryCache.delete(key); } }); }, 600000); // 每10分钟清理一次 // 页面卸载时清理 window.addEventListener('beforeunload', () => { memoryCache.clear(); }); } // 启动初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } // 暴露清理缓存的接口(用于调试) window.clearCardCache = function() { memoryCache.clear(); StorageCache.clear(); console.log('卡牌缓存已清理'); }; })(); // 角色图片切换功能 $(document).ready(function() { // 使用事件委托来确保动态内容也能响应 $(document).on('click', '.character-switch-btn', function() { // 如果点击的是已经激活的按钮,不执行任何操作 if ($(this).hasClass('active')) { return; } var targetType = $(this).attr('data-target'); var container = $(this).closest('#character-container'); var imageWrapper = container.find('.character-image-wrapper'); var allImages = imageWrapper.find('.character-image'); // 先将所有图片淡出 allImages.each(function() { $(this).css('opacity', '0'); }); // 延迟后切换显示状态 setTimeout(function() { allImages.each(function() { $(this).css('display', 'none'); }); // 显示目标图片 imageWrapper.find('[data-image-type="' + targetType + '"]').each(function() { $(this).css('display', 'block'); // 强制重绘 $(this)[0].offsetHeight; $(this).css('opacity', '1'); }); }, 300); // 更新按钮样式 container.find('.character-switch-btn').each(function() { $(this).removeClass('active'); $(this).css({ 'background': 'rgba(0,0,0,0.5)', 'cursor': 'pointer' }); }); // 设置当前按钮为激活状态 $(this).addClass('active'); $(this).css({ 'background': 'rgba(70, 130, 255, 0.8)', 'cursor': 'default' }); }); // 鼠标悬停效果(仅对非激活按钮有效) $(document).on('mouseenter', '.character-switch-btn:not(.active)', function() { $(this).css('background', 'rgba(70, 130, 255, 0.5)'); }); $(document).on('mouseleave', '.character-switch-btn:not(.active)', function() { $(this).css('background', 'rgba(0,0,0,0.5)'); }); }); /* 轮播图功能 */ $(function() { $('.carousel-container').each(function() { var $container = $(this); var $wrapper = $container.find('.carousel-wrapper'); var $slides = $container.find('.carousel-slide'); var $titleItems = $container.find('.carousel-title-item'); var slideCount = $slides.length; var currentSlide = 0; var autoPlayInterval; var isTransitioning = false; // 切换到指定幻灯片 function goToSlide(index) { if (isTransitioning) return; if (index < 0) index = slideCount - 1; if (index >= slideCount) index = 0; isTransitioning = true; currentSlide = index; $wrapper.css('transform', 'translateX(-' + (index * 100) + '%)'); // 更新标题状态 $titleItems.each(function(i) { var $item = $(this); var $text = $item.find('.title-text'); var $indicator = $item.find('.title-indicator'); if (i === index) { $item.addClass('active'); $text.css('opacity', '1').css('font-weight', 'bold'); $indicator.css('background', '#ff6600'); } else { $item.removeClass('active'); $text.css('opacity', '0.7').css('font-weight', 'normal'); $indicator.css('background', 'transparent'); } }); setTimeout(function() { isTransitioning = false; }, 500); } // 下一张 function nextSlide() { goToSlide(currentSlide + 1); } // 上一张 function prevSlide() { goToSlide(currentSlide - 1); } // 自动播放 function startAutoPlay() { autoPlayInterval = setInterval(nextSlide, 10000); } // 停止自动播放 function stopAutoPlay() { clearInterval(autoPlayInterval); } // 绑定左右切换按钮事件(处理图片点击) $container.find('.carousel-next').click(function(e) { e.preventDefault(); e.stopPropagation(); stopAutoPlay(); nextSlide(); startAutoPlay(); }); $container.find('.carousel-prev').click(function(e) { e.preventDefault(); e.stopPropagation(); stopAutoPlay(); prevSlide(); startAutoPlay(); }); // 防止按钮内的图片链接跳转 $container.find('.carousel-btn img, .carousel-btn a').click(function(e) { e.preventDefault(); return false; }); // 绑定标题点击事件 $titleItems.click(function() { var slideIndex = parseInt($(this).attr('data-slide')); stopAutoPlay(); goToSlide(slideIndex); startAutoPlay(); }); // 鼠标悬停在容器时暂停 $container.hover( function() { stopAutoPlay(); }, function() { startAutoPlay(); } ); // 触摸滑动支持(移动设备) var touchStartX = 0; var touchEndX = 0; $container.on('touchstart', function(e) { touchStartX = e.originalEvent.changedTouches[0].screenX; }); $container.on('touchend', function(e) { touchEndX = e.originalEvent.changedTouches[0].screenX; handleSwipe(); }); function handleSwipe() { if (touchEndX < touchStartX - 50) { stopAutoPlay(); nextSlide(); startAutoPlay(); } if (touchEndX > touchStartX + 50) { stopAutoPlay(); prevSlide(); startAutoPlay(); } } // 键盘控制 $(document).keydown(function(e) { if ($container.is(':hover')) { if (e.keyCode === 37) { // 左箭头 stopAutoPlay(); prevSlide(); startAutoPlay(); } else if (e.keyCode === 39) { // 右箭头 stopAutoPlay(); nextSlide(); startAutoPlay(); } } }); // 启动自动播放 if (slideCount > 1) { startAutoPlay(); } }); }); /* 悬浮目录 */ $(document).ready(function() { // 只在有目录的页面上执行 if ($('.toc').length > 0) { // 创建侧边目录 var $sidebar = $('<div id="toc-sidebar"><div id="toc-sidebar-trigger">展开目录</div><div id="toc-sidebar-content"></div></div>'); $('body').append($sidebar); // 提取并修复目录内容 var tocUl = $('<ul></ul>'); // 避免重复的目录项 var processedItems = new Set(); // 从原始目录构建新目录 $('.toc ul li').each(function() { var $link = $(this).find('a').first(); var href = $link.attr('href'); var $number = $link.find('.tocnumber').first(); var $text = $link.find('.toctext').first(); // 创建唯一标识符,避免重复添加 var itemId = $number.text() + '-' + $text.text(); if (!processedItems.has(itemId)) { processedItems.add(itemId); // 创建新的目录项 var $li = $('<li></li>'); var $newLink = $('
').attr('href', href); // 如果有编号,则添加编号 if ($number.length) { $newLink.append($('<span class="tocnumber"></span>').text($number.text())); $newLink.append(' '); } $newLink.append($('<span class="toctext"></span>').text($text.text())); $li.append($newLink); tocUl.append($li); } }); $('#toc-sidebar-content').append(tocUl); // 点击展开/折叠事件处理 $('#toc-sidebar-trigger').click(function() { $('#toc-sidebar').toggleClass('expanded'); // 根据展开/折叠状态更改按钮文字 if ($('#toc-sidebar').hasClass('expanded')) { $('#toc-sidebar-trigger').text('隐藏目录'); } else { $('#toc-sidebar-trigger').text('展开目录'); } }); } }); // 卡牌悬浮显示功能 $(function() { // 初始化所有卡牌悬浮 function initCardHoverElements() { $('.card-hover-container').each(function() { var $container = $(this); // 只初始化尚未处理的元素 if ($container.data('initialized')) return; $container.data('initialized', true); // 获取卡牌数据 var character = $container.data('character'); var cardName = $container.data('card'); var deckType = $container.data('deck') || ''; var index = $container.data('index') || 0; var $popup = $container.find('.card-popup'); // 预加载卡牌数据 $container.on('mouseenter', function() { // 如果卡牌数据已经加载过,直接显示 if ($popup.data('loaded')) { // 调整位置到右下方 positionCardPopup($container); return; } // 加载卡牌数据 var params = { action: 'parse', text: '{{#invoke:卡牌|main|' + character + '|' + cardName + '|' + deckType + '|' + index + '}}', prop: 'text', disablelimitreport: true, format: 'json' }; $.ajax({ url: mw.util.wikiScript('api'), data: params, dataType: 'json', success: function(data) { if (data && data.parse && data.parse.text) { var cardHtml = data.parse.text['*']; $popup.html(cardHtml).data('loaded', true); // 调整位置到右下方 positionCardPopup($container); } }, error: function() { $popup.html('<div style="color: #721c24;">无法加载卡牌数据</div>').data('loaded', true); } }); }); }); } // 调整卡牌弹出位置到右下方 function positionCardPopup($container) { var $popupContainer = $container.find('.card-popup-container'); var containerWidth = $container.width(); var windowWidth = $(window).width(); var containerOffset = $container.offset(); var rightSpace = windowWidth - containerOffset.left - containerWidth; // 重置位置 $popupContainer.css({ 'left': 'auto', 'right': 'auto', 'top': '100%', 'margin-top': '5px' }); // 如果右侧空间足够,放在右下方 if (rightSpace >= 168) { // 卡牌宽度大约168px $popupContainer.css({ 'left': '0', }); } // 如果右侧空间不够,但左侧空间足够,放在左下方 else if (containerOffset.left >= 168) { $popupContainer.css({ 'right': '0', }); } // 如果两侧都不够,尝试居中并确保完全可见 else { var leftPosition = Math.max(0, Math.min(containerOffset.left - (168/2), windowWidth - 168)); $popupContainer.css({ 'left': (leftPosition - containerOffset.left) + 'px' }); } } // 初次加载页面时初始化 $(document).ready(function() { initCardHoverElements(); }); // 使用 MutationObserver 监听 DOM 变化,处理动态加载的内容 if (window.MutationObserver) { var observer = new MutationObserver(function(mutations) { var shouldInit = false; mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length) { shouldInit = true; } }); if (shouldInit) { initCardHoverElements(); } }); observer.observe(document.body, { childList: true, subtree: true }); } }); (function() { // 在现有代码基础上添加以下功能 // 创建全局悬浮预览容器 var hoverPreviewContainer = null; var hoverTimeout = null; function createHoverPreview() { if (!hoverPreviewContainer) { hoverPreviewContainer = document.createElement('div'); hoverPreviewContainer.id = 'card-hover-preview'; hoverPreviewContainer.style.cssText = ` display: none; position: fixed; z-index: 9998; pointer-events: none; transition: opacity 0.2s; `; document.body.appendChild(hoverPreviewContainer); } return hoverPreviewContainer; } function showHoverPreview(element) { var container = createHoverPreview(); var character = element.dataset.character; var card = element.dataset.card; var deck = element.dataset.deck || ''; var index = element.dataset.index || ''; // 清除之前的定时器 if (hoverTimeout) { clearTimeout(hoverTimeout); } // 延迟显示,避免快速移动时频繁触发 hoverTimeout = setTimeout(function() { fetchCardHTML(character, card, deck, function(html) { // 创建卡牌容器 var cardWrapper = document.createElement('div'); cardWrapper.style.cssText = ` background: rgba(0, 0, 0, 0.95); border: 2px solid #4a90e2; border-radius: 8px; padding: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.8); transform: scale(1.2); `; cardWrapper.innerHTML = html; // 禁用预览卡牌的点击事件 var cards = cardWrapper.querySelectorAll('.game-card'); cards.forEach(function(card) { card.style.cursor = 'default'; card.onclick = null; }); container.innerHTML = ''; container.appendChild(cardWrapper); // 计算位置 var rect = element.getBoundingClientRect(); var previewWidth = 220; // 168 * 1.2 + padding var previewHeight = 296; // 230 * 1.2 + padding var left = rect.left + rect.width / 2 - previewWidth / 2; var top = rect.bottom + 10; // 调整位置,确保不超出屏幕 if (left < 10) left = 10; if (left + previewWidth > window.innerWidth - 10) { left = window.innerWidth - previewWidth - 10; } if (top + previewHeight > window.innerHeight - 10) { // 显示在上方 top = rect.top - previewHeight - 10; } container.style.left = left + 'px'; container.style.top = top + 'px'; container.style.display = 'block'; container.style.opacity = '1'; }); }, 200); // 200ms 延迟 } function hideHoverPreview() { if (hoverTimeout) { clearTimeout(hoverTimeout); hoverTimeout = null; } if (hoverPreviewContainer) { hoverPreviewContainer.style.opacity = '0'; setTimeout(function() { if (hoverPreviewContainer) { hoverPreviewContainer.style.display = 'none'; hoverPreviewContainer.innerHTML = ''; } }, 200); } } // 初始化悬浮事件 function initHoverEvents() { // 使用事件委托处理悬浮 document.addEventListener('mouseenter', function(e) { var container = e.target.closest('.card-hover-container'); if (container) { showHoverPreview(container); } }, true); document.addEventListener('mouseleave', function(e) { var container = e.target.closest('.card-hover-container'); if (container && !container.contains(e.relatedTarget)) { hideHoverPreview(); } }, true); // 点击时显示放大版本 document.addEventListener('click', function(e) { var container = e.target.closest('.card-hover-container'); if (container) { e.preventDefault(); e.stopPropagation(); hideHoverPreview(); // 获取卡牌数据并显示 var character = container.dataset.character; var card = container.dataset.card; var deck = container.dataset.deck || ''; fetchCardHTML(character, card, deck, function(html) { var tempDiv = document.createElement('div'); tempDiv.innerHTML = html; var cardElement = tempDiv.querySelector('.game-card'); if (cardElement) { showEnlargedCard(cardElement); } }); } }); } // 修改原有的初始化函数 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { initCardClickEvents(); initHoverEvents(); // 添加悬浮事件初始化 }); } else { initCardClickEvents(); initHoverEvents(); } })();
返回
MediaWiki:Common.js
。