卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
MediaWiki
查看“︁CardSys.js”︁的源代码
←
MediaWiki:CardSys.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
(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 requestQueue = []; var activeRequests = 0; var MAX_CONCURRENT_REQUESTS = 3; // 限制最大并发请求数 // 添加请求超时控制 var REQUEST_TIMEOUT = 10000; // 10秒超时 // 智能缓存管理器 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 createErrorPlaceholder(text, scale) { var placeholder = document.createElement('div'); placeholder.className = 'card-error'; var baseStyle = 'width: 168px; height: 230px; background: rgba(255,0,0,0.1); border: 2px dashed rgba(255,0,0,0.3); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #ff6b6b;'; if (scale) { baseStyle += ' transform: scale(' + scale + '); transform-origin: center center;'; } placeholder.style.cssText = baseStyle; placeholder.innerHTML = '<div style="text-align: center; padding: 10px;">' + '<div style="font-size: 30px; margin-bottom: 10px;">⚠</div>' + '<div style="font-size: 12px;">' + (text || '加载失败') + '</div>' + '</div>'; return placeholder; } // 请求队列处理器 function processRequestQueue() { if (requestQueue.length === 0 || activeRequests >= MAX_CONCURRENT_REQUESTS) { return; } var request = requestQueue.shift(); activeRequests++; request.execute(function() { activeRequests--; processRequestQueue(); // 处理下一个请求 }); } // 添加到请求队列 function queueRequest(executeFn) { return new Promise(function(resolve, reject) { requestQueue.push({ execute: function(done) { executeFn() .then(function(result) { resolve(result); done(); }) .catch(function(error) { reject(error); done(); }); } }); processRequestQueue(); }); } // 优化的API请求函数,添加超时和错误处理 function fetchCardHTML(character, cardName, deckType, callback) { var cacheKey = character + '|' + cardName + '|' + (deckType || ''); // 检查缓存 var cached = cacheManager.get(cacheKey); if (cached) { callback(cached, null); return; } // 使用请求队列 queueRequest(function() { return new Promise(function(resolve, reject) { var api = new mw.Api(); var wikitext = '{{#invoke:卡牌|main|' + character + '|' + cardName + '|' + (deckType || '') + '}}'; var timeoutId = setTimeout(function() { reject(new Error('请求超时')); }, REQUEST_TIMEOUT); api.parse(wikitext) .done(function(html) { clearTimeout(timeoutId); cacheManager.set(cacheKey, html); resolve(html); }) .fail(function(error) { clearTimeout(timeoutId); console.error('加载卡牌失败:', character, cardName, deckType, error); reject(error); }); }); }) .then(function(html) { callback(html, null); }) .catch(function(error) { callback(null, error); }); } // 批量获取卡牌HTML function fetchCardHTMLBatch(requests, callback) { var results = {}; var errors = {}; 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, errors); return; } // 限制批量请求数量,分批处理 var batchSize = 5; var batches = []; for (var i = 0; i < pending.length; i += batchSize) { batches.push(pending.slice(i, i + batchSize)); } var currentBatch = 0; function processBatch() { if (currentBatch >= batches.length) { callback(results, errors); return; } var batch = batches[currentBatch]; var completed = 0; batch.forEach(function(req) { fetchCardHTML(req.character, req.cardName, req.deckType, function(html, error) { var cacheKey = req.character + '|' + req.cardName + '|' + (req.deckType || ''); if (error) { errors[cacheKey] = error; } else { results[cacheKey] = html; } completed++; if (completed === batch.length) { currentBatch++; // 延迟处理下一批,避免请求过快 setTimeout(processBatch, 200); } }); }); } processBatch(); } // 预加载管理器 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, 500); } } } // 批量处理预加载队列 function processPreloadQueue() { preloadWorker = null; if (preloadQueue.size === 0) return; var batch = Array.from(preloadQueue).slice(0, 2); 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, 1000); } } // 创建遮罩层和容器 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[viewHistory.length - 1]; if (previousView.type === 'enlarged') { showEnlargedCard(previousView.data.element, -1); } else if (previousView.type === 'derivedCards') { showAllDerivedCards(previousView.data.character, previousView.data.derivedCardsList, -1); } else if (previousView.type === 'variantCards') { showVariantCards(previousView.data.character, previousView.data.cardName, previousView.data.variantType, -1); } } else if (viewHistory.length === 1) { closeCardDisplay(); } else { closeCardDisplay(); } } // 检查卡牌变体 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, error) { if (!error && html && !html.includes('找不到卡组')) { variants.lingguang = true; } checkComplete(); }); fetchCardHTML(character, cardName, '神之一闪', function(html, error) { if (!error && html && !html.includes('找不到卡组')) { variants.shenguang = true; } checkComplete(); }); } // 放大显示卡牌 function showEnlargedCard(cardElement, addToHistory) { 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'; addLoadingStyles(); currentCardInfo = { element: cardElement, cardName: cardName, character: character, deckType: deckType, derivedCards: derivedCards }; if (addToHistory === -1) { if (viewHistory.length > 0) { viewHistory[viewHistory.length - 1] = { type: 'enlarged', data: currentCardInfo }; } } else if (addToHistory !== false) { 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, error) { if (error || !html) { var errorPlaceholder = createErrorPlaceholder('加载失败', 1.5); derivedCardWrapper.removeChild(placeholder); derivedCardWrapper.appendChild(errorPlaceholder); return; } 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, true); }; 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;'; 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) { if (buttonsContainer.contains(checkingVariants)) { 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, '灵光一闪', true); }; 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, '神之一闪', true); }; 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); if (viewHistory.length > 1) { 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()); elements.overlay.style.display = 'block'; } // 显示所有衍生卡牌 function showAllDerivedCards(character, derivedCardsList, addToHistory) { var overlay = document.getElementById('card-overlay'); var container = document.getElementById('card-display-container'); if (addToHistory === -1) { if (viewHistory.length > 0) { viewHistory[viewHistory.length - 1] = { type: 'derivedCards', data: { character: character, derivedCardsList: derivedCardsList } }; } } else if (addToHistory === true) { viewHistory.push({ type: 'derivedCards', data: { character: character, derivedCardsList: derivedCardsList } }); } else if (addToHistory === 0) { if (viewHistory.length > 0) { viewHistory.pop(); } 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, errors) { uniqueCards.forEach(function(cardName, index) { var cacheKey = character + '|' + cardName + '|'; if (errors[cacheKey]) { var errorPlaceholder = createErrorPlaceholder('加载失败', null); cardsContainer.replaceChild(errorPlaceholder, placeholders[index]); return; } 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('、'), 0); }; 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) { var overlay = document.getElementById('card-overlay'); var container = document.getElementById('card-display-container'); if (addToHistory === -1) { if (viewHistory.length > 0) { viewHistory[viewHistory.length - 1] = { type: 'variantCards', data: { character: character, cardName: cardName, variantType: variantType } }; } } else if (addToHistory === true) { viewHistory.push({ type: 'variantCards', data: { character: character, cardName: cardName, variantType: variantType } }); } 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; 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;'; var loadingPlaceholder = createLoadingPlaceholder('加载变体卡牌...', null); cardsContainer.appendChild(loadingPlaceholder); container.appendChild(cardsContainer); fetchCardHTML(character, cardName, variantType, function(html, error) { if (error || !html) { cardsContainer.removeChild(loadingPlaceholder); var errorPlaceholder = createErrorPlaceholder('加载变体失败', null); cardsContainer.appendChild(errorPlaceholder); return; } var tempContainer = document.createElement('div'); tempContainer.innerHTML = html; 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('、'), true); }; 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')) { clearTimeout(preloadTimeout); preloadTimeout = setTimeout(function() { var character = card.dataset.character; var cardName = card.dataset.cardName; var derivedCards = card.dataset.derivedCards; if (!character || !cardName) return; // 只在空闲时预加载 if (activeRequests < 2) { preloadCardData(character, cardName, '灵光一闪'); preloadCardData(character, cardName, '神之一闪'); if (derivedCards && derivedCards.trim() !== '') { var cardsList = derivedCards.split('、'); var preloadCount = Math.min(2, cardsList.length); // 减少预加载数量 for (var i = 0; i < preloadCount; i++) { preloadCardData(character, cardsList[i].trim(), ''); } } } }, 500); // 增加延迟 } }); 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); } }); // 延迟初始化预加载,避免影响页面初始加载 setTimeout(function() { initPreloadEvents(); }, 3000); // 页面加载3秒后才启用预加载 addLoadingStyles(); } // 添加键盘快捷键支持 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); }, { passive: true }); // 添加 passive 标志提升性能 } } // 清理函数 - 更激进的清理策略 function cleanup() { if (Object.keys(apiCache).length > cacheManager.maxSize * 1.2) { 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]]; } console.log('缓存清理完成,删除了 ' + toDelete + ' 条记录'); } // 清理预加载队列 if (preloadQueue.size > 10) { preloadQueue.clear(); console.log('预加载队列已清空'); } } // 定期清理(每3分钟) setInterval(cleanup, 3 * 60 * 1000); // 页面卸载时清理 window.addEventListener('beforeunload', function() { apiCache = {}; cacheManager.accessTime = {}; preloadQueue.clear(); }); // 监控内存使用(仅在支持的浏览器中) function monitorMemory() { if (window.performance && window.performance.memory) { var memory = window.performance.memory; var usedPercent = (memory.usedJSHeapSize / memory.jsHeapSizeLimit) * 100; if (usedPercent > 80) { console.warn('内存使用率过高: ' + usedPercent.toFixed(2) + '%'); cleanup(); // 强制清理 } } } // 每分钟检查一次内存 setInterval(monitorMemory, 60 * 1000); // 页面加载完成后初始化 function init() { initCardClickEvents(); initKeyboardShortcuts(); // 延迟执行性能优化,避免阻塞主线程 setTimeout(function() { optimizeScrollPerformance(); }, 1000); console.log('卡牌系统初始化完成'); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();
该页面使用的模板:
模块:Arguments
(
查看源代码
)
模块:卡牌
(
查看源代码
)
模块:卡牌/' + character + '
(
查看源代码
)
模块:卡牌/display
(
查看源代码
)
模块:词典/data
(
查看源代码
)
返回
MediaWiki:CardSys.js
。