卡厄思
梦
境
菜单
首页
回到首页
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(); } })(); /* 角色立绘切换 */ $(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)'); }); }); /* 悬浮目录 */ $(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() { // 防止重复初始化 if (window.cardSystemInitialized) return; window.cardSystemInitialized = true; // 缓存DOM元素 var overlayCache = null; var containerCache = null; // 保存当前卡牌信息,用于返回 var currentCardInfo = null; // 添加历史栈来记录浏览历史 var viewHistory = []; // API缓存 var apiCache = {}; // 预加载队列 var preloadQueue = new Set(); var preloadWorker = null; // 智能缓存管理器 var cacheManager = { maxSize: 100, // 最大缓存数量 accessTime: {}, // 记录访问时间 set: function(key, value) { apiCache[key] = value; this.accessTime[key] = Date.now(); // 检查缓存大小 var keys = Object.keys(apiCache); if (keys.length > this.maxSize) { // 删除最久未使用的缓存 var oldestKey = keys[0]; var oldestTime = this.accessTime[oldestKey] || 0; for (var i = 1; i < keys.length; i++) { var time = this.accessTime[keys[i]] || 0; if (time < oldestTime) { oldestKey = keys[i]; oldestTime = time; } } delete apiCache[oldestKey]; delete this.accessTime[oldestKey]; } }, get: function(key) { if (apiCache[key]) { this.accessTime[key] = Date.now(); return apiCache[key]; } return null; } }; // 添加Loading动画CSS function addLoadingStyles() { if (!document.getElementById('card-loading-styles')) { var style = document.createElement('style'); style.id = 'card-loading-styles'; style.textContent = ` @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .card-fade-in { animation: fadeIn 0.3s ease-in; } `; document.head.appendChild(style); } } // 创建loading占位符 function createLoadingPlaceholder(text, scale) { var placeholder = document.createElement('div'); placeholder.className = 'card-loading'; var baseStyle = 'width: 168px; height: 230px; background: rgba(255,255,255,0.1); border: 2px dashed rgba(255,255,255,0.3); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white;'; if (scale) { baseStyle += ' transform: scale(' + scale + '); transform-origin: center center;'; } placeholder.style.cssText = baseStyle; placeholder.innerHTML = '<div style="text-align: center;">' + '<div class="loading-spinner" style="border: 3px solid rgba(255,255,255,0.3); border-top: 3px solid white; border-radius: 50%; width: 30px; height: 30px; animation: spin 1s linear infinite; margin: 0 auto 10px;"></div>' + '<div style="font-size: 12px;">' + (text || '加载中...') + '</div>' + '</div>'; return placeholder; } // 预加载管理器 function preloadCardData(character, cardName, deckType) { var cacheKey = character + '|' + cardName + '|' + (deckType || ''); if (!cacheManager.get(cacheKey) && !preloadQueue.has(cacheKey)) { preloadQueue.add(cacheKey); if (!preloadWorker) { preloadWorker = setTimeout(processPreloadQueue, 100); } } } // 批量处理预加载队列 function processPreloadQueue() { preloadWorker = null; if (preloadQueue.size === 0) return; var batch = Array.from(preloadQueue).slice(0, 5); // 每批处理5个 batch.forEach(function(key) { preloadQueue.delete(key); }); batch.forEach(function(cacheKey) { var parts = cacheKey.split('|'); fetchCardHTML(parts[0], parts[1], parts[2], function() { // 预加载完成,数据已缓存 }); }); // 如果还有剩余,继续处理 if (preloadQueue.size > 0) { preloadWorker = setTimeout(processPreloadQueue, 200); } } // 创建遮罩层和容器 function createCardOverlay() { if (overlayCache && containerCache) { return { overlay: overlayCache, container: containerCache }; } // 创建遮罩 var 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;'; // 创建容器 var 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', function(e) { if (e.target === overlay) { closeCardDisplay(); } }); overlayCache = overlay; containerCache = container; return { overlay: overlay, container: container }; } // 创建关闭按钮 function createCloseButton() { var closeBtn = document.createElement('div'); closeBtn.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;'; closeBtn.innerHTML = '<span style="color: white; font-size: 24px; font-weight: bold; line-height: 1;">×</span>'; closeBtn.onmouseover = function() { this.style.background = 'rgba(255,255,255,0.2)'; this.style.transform = 'scale(1.1)'; }; closeBtn.onmouseout = function() { this.style.background = 'rgba(255,255,255,0.1)'; this.style.transform = 'scale(1)'; }; closeBtn.onclick = function() { closeCardDisplay(); }; return closeBtn; } // 关闭卡牌展示 function closeCardDisplay() { var overlay = document.getElementById('card-overlay'); if (overlay) { overlay.style.display = 'none'; var container = overlay.querySelector('#card-display-container'); if (container) { container.innerHTML = ''; } } currentCardInfo = null; viewHistory = []; // 清空历史栈 } // 返回上一层 function goBack() { if (viewHistory.length > 1) { // 移除当前视图 viewHistory.pop(); // 获取上一个视图 var previousView = viewHistory.pop(); // 根据视图类型重新渲染 if (previousView.type === 'enlarged') { showEnlargedCard(previousView.data.element, false); // false 表示不添加到历史 } else if (previousView.type === 'derivedCards') { showAllDerivedCards(previousView.data.character, previousView.data.derivedCardsList, false); } else if (previousView.type === 'variantCards') { showVariantCards(previousView.data.character, previousView.data.cardName, previousView.data.variantType, false); } } else if (viewHistory.length === 1) { // 只剩一层,关闭弹窗 closeCardDisplay(); } } // 获取卡牌HTML function fetchCardHTML(character, cardName, deckType, callback) { var cacheKey = character + '|' + cardName + '|' + (deckType || ''); // 检查缓存 var cached = cacheManager.get(cacheKey); if (cached) { callback(cached); return; } var api = new mw.Api(); var wikitext = '{{#invoke:卡牌|main|' + character + '|' + cardName + '|' + (deckType || '') + '}}'; api.parse(wikitext).done(function(html) { cacheManager.set(cacheKey, html); callback(html); }).fail(function() { callback('<div style="color: white;">加载失败</div>'); }); } // 批量获取卡牌HTML function fetchCardHTMLBatch(requests, callback) { var results = {}; var pending = []; // 先检查缓存 requests.forEach(function(req) { var cacheKey = req.character + '|' + req.cardName + '|' + (req.deckType || ''); var cached = cacheManager.get(cacheKey); if (cached) { results[cacheKey] = cached; } else { pending.push(req); } }); // 如果全部都有缓存,直接返回 if (pending.length === 0) { callback(results); return; } // 批量请求未缓存的 var completed = 0; pending.forEach(function(req) { fetchCardHTML(req.character, req.cardName, req.deckType, function(html) { var cacheKey = req.character + '|' + req.cardName + '|' + (req.deckType || ''); results[cacheKey] = html; completed++; if (completed === pending.length) { callback(results); } }); }); } // 检查卡牌变体 function checkCardVariants(character, cardName, callback) { var variants = { lingguang: false, shenguang: false }; var checkCount = 0; var totalChecks = 2; function checkComplete() { checkCount++; if (checkCount === totalChecks) { callback(variants); } } // 并行检查两种变体 fetchCardHTML(character, cardName, '灵光一闪', function(html) { if (html && !html.includes('找不到卡组')) { variants.lingguang = true; } checkComplete(); }); fetchCardHTML(character, cardName, '神之一闪', function(html) { if (html && !html.includes('找不到卡组')) { variants.shenguang = true; } checkComplete(); }); } // 放大显示卡牌 function showEnlargedCard(cardElement, addToHistory) { if (addToHistory !== false) { addToHistory = true; } var elements = createCardOverlay(); var container = elements.container; var cardName = cardElement.dataset.cardName; var character = cardElement.dataset.character; var deckType = cardElement.dataset.deckType; var derivedCards = cardElement.dataset.derivedCards; var hasMechanism = cardElement.dataset.hasMechanism === 'true'; // 添加Loading样式 addLoadingStyles(); // 保存当前卡牌信息 currentCardInfo = { element: cardElement, cardName: cardName, character: character, deckType: deckType, derivedCards: derivedCards }; // 添加到历史栈 if (addToHistory) { viewHistory.push({ type: 'enlarged', data: currentCardInfo }); } // 重置容器样式 container.style.cssText = 'position: relative; min-height: 100vh; padding: 40px 20px; display: flex; align-items: center; justify-content: center;'; // 创建内容包装器 var contentWrapper = document.createElement('div'); contentWrapper.style.cssText = 'display: flex; align-items: flex-start; gap: 0px; position: relative;'; // 立即显示主卡牌 var centerContainer = document.createElement('div'); centerContainer.style.cssText = 'display: flex; flex-direction: column; align-items: center; gap: 0px;'; var mainCardContainer = document.createElement('div'); mainCardContainer.style.cssText = 'width: 336px; height: 460px; display: flex; align-items: center; justify-content: center; position: relative;'; var cardInner = document.createElement('div'); cardInner.style.cssText = 'transform: scale(2); position: relative;'; var enlargedCard = cardElement.cloneNode(true); enlargedCard.style.width = '168px'; enlargedCard.style.height = '230px'; enlargedCard.style.cursor = 'default'; enlargedCard.style.position = 'relative'; enlargedCard.style.display = 'block'; enlargedCard.onclick = null; enlargedCard.classList.add('card-fade-in'); cardInner.appendChild(enlargedCard); mainCardContainer.appendChild(cardInner); centerContainer.appendChild(mainCardContainer); // 处理衍生卡牌 if (derivedCards && derivedCards.trim() !== '') { var leftContainer = document.createElement('div'); leftContainer.style.cssText = 'display: flex; flex-direction: column; gap: 0px; align-items: center;'; var derivedCardsList = derivedCards.split('、'); var derivedCardWrapper = document.createElement('div'); derivedCardWrapper.style.cssText = 'width: 252px; height: 345px; display: flex; align-items: center; justify-content: center;'; // 先显示占位符 var placeholder = createLoadingPlaceholder('加载衍生卡牌...', 1.5); derivedCardWrapper.appendChild(placeholder); leftContainer.appendChild(derivedCardWrapper); // 异步加载衍生卡牌 fetchCardHTML(character, derivedCardsList[0].trim(), '', function(html) { var firstDerivedCard = document.createElement('div'); firstDerivedCard.id = 'derived-cards-display'; firstDerivedCard.style.cssText = 'transform: scale(1.5); transform-origin: center center; opacity: 0;'; firstDerivedCard.innerHTML = html; var cards = firstDerivedCard.querySelectorAll('.game-card'); cards.forEach(function(card) { card.style.cursor = 'default'; card.onclick = function(e) { e.stopPropagation(); e.preventDefault(); }; }); derivedCardWrapper.removeChild(placeholder); derivedCardWrapper.appendChild(firstDerivedCard); // 淡入动画 setTimeout(function() { firstDerivedCard.style.transition = 'opacity 0.3s'; firstDerivedCard.style.opacity = '1'; }, 10); }); // 如果有多个衍生卡牌,添加查看全部按钮 if (derivedCardsList.length > 1) { var viewAllBtn = document.createElement('div'); viewAllBtn.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; margin-top: 0px;'; viewAllBtn.textContent = '查看所有衍生卡牌'; viewAllBtn.onmouseover = function() { this.style.transform = 'scale(1.05)'; }; viewAllBtn.onmouseout = function() { this.style.transform = 'scale(1)'; }; viewAllBtn.onclick = function() { showAllDerivedCards(character, derivedCardsList); }; leftContainer.appendChild(viewAllBtn); } contentWrapper.appendChild(leftContainer); } // 创建按钮容器(异步检查变体) var buttonsContainer = document.createElement('div'); buttonsContainer.style.cssText = 'display: flex; gap: 15px; white-space: nowrap; min-height: 50px; align-items: center; justify-content: center;'; // 添加loading指示器 var checkingVariants = document.createElement('div'); checkingVariants.style.cssText = 'color: rgba(255,255,255,0.5); font-size: 12px;'; checkingVariants.textContent = '检查变体卡牌...'; buttonsContainer.appendChild(checkingVariants); centerContainer.appendChild(buttonsContainer); // 异步检查变体 checkCardVariants(character, cardName, function(variants) { buttonsContainer.removeChild(checkingVariants); if (variants.lingguang) { var lingguangBtn = document.createElement('div'); lingguangBtn.style.cssText = 'padding: 10px 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 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; opacity: 0;'; lingguangBtn.textContent = '灵光一闪'; lingguangBtn.onmouseover = function() { this.style.transform = 'scale(1.05)'; }; lingguangBtn.onmouseout = function() { this.style.transform = 'scale(1)'; }; lingguangBtn.onclick = function() { showVariantCards(character, cardName, '灵光一闪'); }; buttonsContainer.appendChild(lingguangBtn); // 淡入动画 setTimeout(function() { lingguangBtn.style.transition = 'opacity 0.3s'; lingguangBtn.style.opacity = '1'; }, 10); } if (variants.shenguang) { var shenguangBtn = document.createElement('div'); shenguangBtn.style.cssText = 'padding: 10px 30px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 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; opacity: 0;'; shenguangBtn.textContent = '神之一闪'; shenguangBtn.onmouseover = function() { this.style.transform = 'scale(1.05)'; }; shenguangBtn.onmouseout = function() { this.style.transform = 'scale(1)'; }; shenguangBtn.onclick = function() { showVariantCards(character, cardName, '神之一闪'); }; buttonsContainer.appendChild(shenguangBtn); // 淡入动画 setTimeout(function() { shenguangBtn.style.transition = 'opacity 0.3s'; shenguangBtn.style.opacity = '1'; }, 10); } // 如果没有变体,移除按钮容器 if (!variants.lingguang && !variants.shenguang) { centerContainer.removeChild(buttonsContainer); } }); contentWrapper.appendChild(centerContainer); // 添加右侧机制说明 if (hasMechanism) { var mechanismContainer = cardElement.nextElementSibling; if (mechanismContainer && mechanismContainer.classList.contains('mechanism-container')) { var mechanismDisplay = document.createElement('div'); mechanismDisplay.style.cssText = 'display: flex; flex-direction: column; gap: 0px; max-width: 320px; min-width: 280px;'; mechanismDisplay.innerHTML = mechanismContainer.innerHTML; mechanismDisplay.style.display = 'flex'; contentWrapper.appendChild(mechanismDisplay); } } container.innerHTML = ''; container.appendChild(contentWrapper); container.appendChild(createCloseButton()); elements.overlay.style.display = 'block'; } // 显示所有衍生卡牌 function showAllDerivedCards(character, derivedCardsList, addToHistory) { if (addToHistory !== false) { addToHistory = true; } var overlay = document.getElementById('card-overlay'); var container = document.getElementById('card-display-container'); // 添加到历史栈 if (addToHistory) { viewHistory.push({ type: 'derivedCards', data: { character: character, derivedCardsList: derivedCardsList } }); } // 清空当前内容 container.innerHTML = ''; container.style.cssText = 'position: relative; padding: 40px; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center;'; // 创建标题 var title = document.createElement('div'); title.style.cssText = 'color: white; font-size: 28px; font-weight: bold; margin-bottom: 30px; text-align: center;'; title.textContent = '衍生卡牌'; container.appendChild(title); // 创建卡牌容器 var 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;'; // 先添加占位符 var uniqueCards = [...new Set(derivedCardsList.map(function(name) { return name.trim(); }))]; var placeholders = []; uniqueCards.forEach(function() { var placeholder = createLoadingPlaceholder('加载中...', null); placeholders.push(placeholder); cardsContainer.appendChild(placeholder); }); container.appendChild(cardsContainer); // 批量加载卡牌 var requests = uniqueCards.map(function(cardName) { return { character: character, cardName: cardName, deckType: '' }; }); fetchCardHTMLBatch(requests, function(results) { uniqueCards.forEach(function(cardName, index) { var cacheKey = character + '|' + cardName + '|'; var html = results[cacheKey]; if (html) { var cardWrapper = document.createElement('div'); cardWrapper.style.cssText = 'opacity: 0;'; cardWrapper.innerHTML = html; var cards = cardWrapper.querySelectorAll('.game-card'); cards.forEach(function(card) { card.style.cursor = 'default'; card.onclick = function(e) { e.stopPropagation(); e.preventDefault(); }; // 检查是否有衍生卡牌 var derivedCards = card.dataset.derivedCards; if (derivedCards && derivedCards.trim() !== '') { var buttonContainer = document.createElement('div'); buttonContainer.style.cssText = 'display: flex; flex-direction: column; align-items: center; gap: 10px;'; var cardContainer = document.createElement('div'); cardContainer.appendChild(card.cloneNode(true)); buttonContainer.appendChild(cardContainer); var viewDerivedBtn = document.createElement('div'); viewDerivedBtn.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;'; viewDerivedBtn.textContent = '查看衍生卡牌'; viewDerivedBtn.onmouseover = function() { this.style.transform = 'scale(1.05)'; }; viewDerivedBtn.onmouseout = function() { this.style.transform = 'scale(1)'; }; viewDerivedBtn.onclick = function(e) { e.stopPropagation(); showAllDerivedCards(character, derivedCards.split('、')); }; buttonContainer.appendChild(viewDerivedBtn); // 替换占位符 cardsContainer.replaceChild(buttonContainer, placeholders[index]); // 淡入动画 setTimeout(function() { buttonContainer.style.transition = 'opacity 0.3s'; buttonContainer.style.opacity = '1'; }, 10); } else { // 替换占位符 cardsContainer.replaceChild(card, placeholders[index]); // 淡入动画 setTimeout(function() { card.style.transition = 'opacity 0.3s'; card.style.opacity = '1'; }, 10); } }); } }); }); // 添加返回按钮 var backBtn = document.createElement('div'); backBtn.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;'; backBtn.textContent = '← 返回'; backBtn.onmouseover = function() { this.style.transform = 'scale(1.05)'; }; backBtn.onmouseout = function() { this.style.transform = 'scale(1)'; }; backBtn.onclick = function() { goBack(); }; container.appendChild(backBtn); // 添加关闭按钮 container.appendChild(createCloseButton()); } // 显示变体卡牌 function showVariantCards(character, cardName, variantType, addToHistory) { if (addToHistory !== false) { addToHistory = true; } var overlay = document.getElementById('card-overlay'); var container = document.getElementById('card-display-container'); // 添加到历史栈 if (addToHistory) { viewHistory.push({ type: 'variantCards', data: { character: character, cardName: cardName, variantType: variantType } }); } // 重置容器样式 container.style.cssText = 'position: relative; padding: 40px; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center;'; container.innerHTML = ''; // 创建标题 var 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; container.appendChild(title); // 创建卡牌容器 var cardsContainer = document.createElement('div'); cardsContainer.style.cssText = 'display: flex; flex-wrap: nowrap; gap: 0px; justify-content: center; max-width: 1400px; overflow-x: auto; padding: 40px; transform: scale(1.5); transform-origin: center center;'; // 先添加loading占位符 var loadingPlaceholder = createLoadingPlaceholder('加载变体卡牌...', null); cardsContainer.appendChild(loadingPlaceholder); container.appendChild(cardsContainer); // 加载变体卡牌 fetchCardHTML(character, cardName, variantType, function(html) { var tempContainer = document.createElement('div'); tempContainer.innerHTML = html; // 移除loading占位符 cardsContainer.removeChild(loadingPlaceholder); // 处理所有卡牌 var cards = tempContainer.querySelectorAll('.game-card'); cards.forEach(function(card, index) { card.style.cursor = 'default'; card.onclick = null; card.style.flexShrink = '0'; card.style.opacity = '0'; // 获取衍生卡牌数据 var derivedCards = card.getAttribute('data-derived-cards'); // 更严格的检查 var hasDerivedCards = false; if (derivedCards !== null && derivedCards !== undefined) { var trimmedValue = String(derivedCards).trim(); if (trimmedValue.length > 0 && trimmedValue !== 'undefined' && trimmedValue !== 'null' && trimmedValue !== 'false' && trimmedValue !== '0') { hasDerivedCards = true; } } if (hasDerivedCards) { // 创建包装器,包含卡牌和按钮 var cardWrapper = document.createElement('div'); cardWrapper.style.cssText = 'display: flex; flex-direction: column; align-items: center; gap: 10px; flex-shrink: 0; opacity: 0;'; // 添加卡牌 var cardClone = card.cloneNode(true); cardClone.style.cursor = 'default'; cardClone.onclick = null; cardClone.style.opacity = '1'; cardWrapper.appendChild(cardClone); // 创建查看衍生卡牌按钮 var viewDerivedBtn = document.createElement('div'); viewDerivedBtn.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;'; viewDerivedBtn.textContent = '查看衍生卡牌'; viewDerivedBtn.onmouseover = function() { this.style.transform = 'scale(1.05)'; }; viewDerivedBtn.onmouseout = function() { this.style.transform = 'scale(1)'; }; // 保存衍生卡牌信息 viewDerivedBtn.setAttribute('data-derived-list', derivedCards); viewDerivedBtn.onclick = function(e) { e.stopPropagation(); var derivedList = this.getAttribute('data-derived-list'); showAllDerivedCards(character, derivedList.split('、')); }; cardWrapper.appendChild(viewDerivedBtn); cardsContainer.appendChild(cardWrapper); // 淡入动画 setTimeout(function() { cardWrapper.style.transition = 'opacity 0.3s'; cardWrapper.style.opacity = '1'; }, 50 * index); } else { // 没有衍生卡牌,直接添加卡牌 cardsContainer.appendChild(card); // 淡入动画 setTimeout(function() { card.style.transition = 'opacity 0.3s'; card.style.opacity = '1'; }, 50 * index); } }); }); // 添加返回按钮 var backBtn = document.createElement('div'); backBtn.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;'; backBtn.textContent = '← 返回'; backBtn.onmouseover = function() { this.style.transform = 'scale(1.05)'; }; backBtn.onmouseout = function() { this.style.transform = 'scale(1)'; }; backBtn.onclick = function() { goBack(); }; container.appendChild(backBtn); // 添加关闭按钮 container.appendChild(createCloseButton()); } // 鼠标悬停时预加载 function initPreloadEvents() { var preloadTimeout = null; document.addEventListener('mouseover', function(e) { var card = e.target.closest('.game-card'); if (card && !card.closest('#card-overlay')) { // 延迟200ms开始预加载,避免快速移动时的无效预加载 clearTimeout(preloadTimeout); preloadTimeout = setTimeout(function() { var character = card.dataset.character; var cardName = card.dataset.cardName; var derivedCards = card.dataset.derivedCards; if (!character || !cardName) return; // 预加载变体 preloadCardData(character, cardName, '灵光一闪'); preloadCardData(character, cardName, '神之一闪'); // 预加载衍生卡牌(最多预加载前3张) if (derivedCards && derivedCards.trim() !== '') { var cardsList = derivedCards.split('、'); var preloadCount = Math.min(3, cardsList.length); for (var i = 0; i < preloadCount; i++) { preloadCardData(character, cardsList[i].trim(), ''); } } }, 200); } }); document.addEventListener('mouseout', function(e) { var card = e.target.closest('.game-card'); if (card && !card.closest('#card-overlay')) { clearTimeout(preloadTimeout); } }); } // 初始化卡牌点击事件 function initCardClickEvents() { // 使用事件委托 document.addEventListener('click', function(e) { var card = e.target.closest('.game-card'); if (card && !card.closest('#card-overlay')) { e.preventDefault(); showEnlargedCard(card); } }); // 添加预加载事件 initPreloadEvents(); // 添加Loading样式 addLoadingStyles(); // 页面加载完成后,预加载可见卡牌的相关数据 setTimeout(function() { var visibleCards = document.querySelectorAll('.game-card:not(#card-overlay .game-card)'); var preloadList = []; visibleCards.forEach(function(card, index) { // 只预加载前10张可见卡牌 if (index >= 10) return; var character = card.dataset.character; var cardName = card.dataset.cardName; if (character && cardName) { preloadList.push({ character: character, cardName: cardName }); } }); // 分批预加载 preloadList.forEach(function(item, index) { setTimeout(function() { preloadCardData(item.character, item.cardName, '灵光一闪'); preloadCardData(item.character, item.cardName, '神之一闪'); }, index * 100); // 每100ms预加载一个 }); }, 2000); // 页面加载2秒后开始预加载 } // 添加键盘快捷键支持 function initKeyboardShortcuts() { document.addEventListener('keydown', function(e) { var overlay = document.getElementById('card-overlay'); if (overlay && overlay.style.display !== 'none') { if (e.key === 'Escape') { e.preventDefault(); closeCardDisplay(); } else if (e.key === 'Backspace' || e.key === 'ArrowLeft') { e.preventDefault(); goBack(); } } }); } // 优化滚动性能 function optimizeScrollPerformance() { var scrollTimeout; var overlay = document.getElementById('card-overlay'); if (overlay) { overlay.addEventListener('scroll', function() { if (!overlay.classList.contains('is-scrolling')) { overlay.classList.add('is-scrolling'); } clearTimeout(scrollTimeout); scrollTimeout = setTimeout(function() { overlay.classList.remove('is-scrolling'); }, 150); }); } } // 添加性能监控 function addPerformanceMonitoring() { if (window.performance && window.performance.mark) { // 监控API调用时间 var originalFetch = fetchCardHTML; fetchCardHTML = function(character, cardName, deckType, callback) { var startMark = 'fetch-start-' + Date.now(); var endMark = 'fetch-end-' + Date.now(); performance.mark(startMark); originalFetch(character, cardName, deckType, function(result) { performance.mark(endMark); performance.measure('API Call: ' + cardName, startMark, endMark); callback(result); }); }; } } // 清理函数 function cleanup() { // 清理大型缓存 if (Object.keys(apiCache).length > cacheManager.maxSize * 1.5) { var keys = Object.keys(apiCache); var toDelete = keys.length - cacheManager.maxSize; // 根据访问时间排序 keys.sort(function(a, b) { return (cacheManager.accessTime[a] || 0) - (cacheManager.accessTime[b] || 0); }); // 删除最旧的条目 for (var i = 0; i < toDelete; i++) { delete apiCache[keys[i]]; delete cacheManager.accessTime[keys[i]]; } } } // 定期清理(每5分钟) setInterval(cleanup, 5 * 60 * 1000); // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { initCardClickEvents(); initKeyboardShortcuts(); optimizeScrollPerformance(); // 仅在开发环境启用性能监控 if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { addPerformanceMonitoring(); } }); } else { initCardClickEvents(); initKeyboardShortcuts(); optimizeScrollPerformance(); // 仅在开发环境启用性能监控 if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { addPerformanceMonitoring(); } } })(); /* 卡牌文字滚动 */ (function() { 'use strict'; function initCardScroll() { var cards = document.querySelectorAll('.game-card.card-description-scrollable'); cards.forEach(function(card) { var scrollContainer = card.querySelector('.card-description-scroll'); var scrollInner = card.querySelector('.card-description-scroll-inner'); var scrollText = card.querySelector('.card-description-text'); if (!scrollContainer || !scrollInner || !scrollText) { return; } // 强制触发重绘 scrollInner.style.display = 'none'; scrollInner.offsetHeight; // 触发重排 scrollInner.style.display = 'block'; }); } // 延迟初始化,确保DOM完全加载 function delayedInit() { setTimeout(initCardScroll, 100); setTimeout(initCardScroll, 500); setTimeout(initCardScroll, 1000); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', delayedInit); } else { delayedInit(); } })(); /* 卡牌Tooltip */ $(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 }); } }); /* 词典Tooltip */ (function() { var tooltipContainer = null; var currentTerm = null; var hideTimeout = null; // 初始化 $(function() { // 创建全局 tooltip 容器 tooltipContainer = $('<div class="dictionary-tooltip-container"></div>'); $('body').append(tooltipContainer); // 鼠标进入词条 $(document).on('mouseenter', '.dictionary-term', function(e) { var $term = $(this); currentTerm = $term; // 清除隐藏定时器 if (hideTimeout) { clearTimeout(hideTimeout); hideTimeout = null; } // 获取 tooltip 内容 var content = $term.attr('data-tooltip-content'); if (!content) return; // 设置内容 tooltipContainer.html(content); // 计算位置 updateTooltipPosition($term); // 显示 tooltip tooltipContainer.addClass('active'); }); // 鼠标离开词条 $(document).on('mouseleave', '.dictionary-term', function() { hideTimeout = setTimeout(function() { tooltipContainer.removeClass('active'); currentTerm = null; }, 100); }); // 鼠标进入 tooltip(防止快速隐藏) tooltipContainer.on('mouseenter', function() { if (hideTimeout) { clearTimeout(hideTimeout); hideTimeout = null; } }); // 鼠标离开 tooltip tooltipContainer.on('mouseleave', function() { hideTimeout = setTimeout(function() { tooltipContainer.removeClass('active'); currentTerm = null; }, 100); }); // 窗口滚动时更新位置 $(window).on('scroll resize', function() { if (currentTerm && tooltipContainer.hasClass('active')) { updateTooltipPosition(currentTerm); } }); }); // 更新 tooltip 位置 function updateTooltipPosition($term) { var rect = $term[0].getBoundingClientRect(); var scrollTop = $(window).scrollTop(); var scrollLeft = $(window).scrollLeft(); // 基本位置:词条下方 var top = rect.bottom + scrollTop + 2; var left = rect.left + scrollLeft; // 获取 tooltip 尺寸 var tooltipWidth = 250; // 固定宽度 var tooltipHeight = tooltipContainer.outerHeight(); // 获取窗口尺寸 var windowWidth = $(window).width(); var windowHeight = $(window).height(); // 检查右边界 if (left + tooltipWidth > windowWidth + scrollLeft) { left = Math.max(scrollLeft, rect.right + scrollLeft - tooltipWidth); } // 检查下边界 if (rect.bottom + tooltipHeight > windowHeight) { // 如果下方空间不足,显示在上方 if (rect.top - tooltipHeight > 0) { top = rect.top + scrollTop - tooltipHeight - 2; } } // 设置位置 tooltipContainer.css({ top: top + 'px', left: left + 'px' }); } })();
返回
MediaWiki:Common.js
。