MediaWiki

MediaWiki:CardSys.js

来自卡厄思梦境WIKI

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
(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();
    }
})();