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