首页
旅人图鉴
秘纹图鉴
特殊页面
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
管理员
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */ // ============================================= // 角色属性查看器 - 动态创建版本 // ============================================= // 角色数据管理器 var CharacterDataManager = { cache: {}, getCharacterData: function(characterId) { var self = this; // 检查缓存 if (self.cache[characterId]) { return Promise.resolve(self.cache[characterId]); } return new Promise(function(resolve, reject) { // 构建数据页面路径 var formattedName = characterId.charAt(0).toUpperCase() + characterId.slice(1); var dataSource = 'Data:Character/' + formattedName + '.json'; $.get("http://trekkers-wiki.jvav.net.cn/index.php", { action: 'raw', page: dataSource }).done(function(data) { console.log("data", data) try { var pageContent = data.parse.text['*']; var jsonMatch = pageContent.match(/\{[\s\S]*\}/); if (!jsonMatch) { reject('在页面中未找到JSON数据: ' + dataSource); return; } var characterData = JSON.parse(jsonMatch[0]); // 缓存数据 self.cache[characterId] = characterData; resolve(characterData); } catch (e) { reject('解析JSON数据失败: ' + e.message); } }).fail(function(error) { reject('API请求失败: ' + error); }); }); }, clearCache: function() { this.cache = {}; } }; // 主初始化函数 $(document).ready(function() { // 添加全局样式 addCharacterStatsStyles(); // 测试代码 // 初始化所有角色属性容器 $('.character-stats-container').each(function() { createCharacterStatsWidget($(this)); }); // 当有新内容加载时也初始化 mw.hook('wikipage.content').add(function($content) { $content.find('.character-stats-container').each(function() { if (!$(this).find('.character-stats-widget').length) { createCharacterStatsWidget($(this)); } }); }); }); // 添加样式到页面 function addCharacterStatsStyles() { if ($('#character-stats-styles').length) { return; // 样式已存在 } var styles = ` <style id="character-stats-styles"> .character-stats-widget { max-width: 800px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); padding: 30px; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .character-header { text-align: center; margin-bottom: 20px; } .character-name { color: #4a6fa5; margin-bottom: 10px; font-size: 28px; } .character-description { color: #666; font-style: italic; font-size: 16px; } .loading-message, .error-message { text-align: center; padding: 20px; color: #666; font-size: 16px; } .error-message { color: #d32f2f; background-color: #ffebee; border-radius: 4px; border: 1px solid #f5c6cb; } .level-selector { margin-bottom: 30px; } .level-display { text-align: center; font-size: 24px; font-weight: bold; margin-bottom: 15px; color: #4a6fa5; } .slider-container { position: relative; margin-bottom: 10px; } .slider-container .level-slider { width: 100%; height: 10px; -webkit-appearance: none; appearance: none; background: linear-gradient(to right, #e0e0e0, #4a6fa5); outline: none; border-radius: 5px; cursor: pointer; } .slider-container .level-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; border-radius: 50%; background: #4a6fa5; cursor: pointer; border: 3px solid white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); transition: all 0.2s; } .slider-container .level-slider::-webkit-slider-thumb:hover { background: #3a5a80; transform: scale(1.1); } .slider-container .level-slider::-moz-range-thumb { width: 24px; height: 24px; border-radius: 50%; background: #4a6fa5; cursor: pointer; border: 3px solid white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .quick-buttons { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 5px; margin-top: 10px; } .level-btn { flex: 1; min-width: 60px; padding: 10px 5px; background-color: #e9ecef; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; transition: all 0.2s; font-size: 14px; } .level-btn:hover { background-color: #d0d8e2; transform: translateY(-2px); } .level-btn.active { background-color: #4a6fa5; color: white; box-shadow: 0 2px 4px rgba(74, 111, 165, 0.3); } .stats-container { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px; } .stat-card { background-color: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); border-left: 4px solid #4a6fa5; transition: transform 0.2s; } .stat-card:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .stat-card.attack { border-left-color: #ff6b6b; } .stat-card.health { border-left-color: #4caf50; } .stat-title { font-size: 18px; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; font-weight: 600; } .stat-card .stat-value { font-size: 32px; font-weight: bold; margin-bottom: 15px; color: #333; } .stat-card .attack .stat-value { color: #ff6b6b; } .stat-card .health .stat-value { color: #4caf50; } .stat-progress { height: 12px; background-color: #e9ecef; border-radius: 6px; overflow: hidden; margin-bottom: 10px; } .stat-bar { height: 100%; border-radius: 6px; width: 0%; transition: width 0.5s ease; } .attack .stat-bar { background: linear-gradient(90deg, #ff6b6b, #ff8e8e); } .health .stat-bar { background: linear-gradient(90deg, #4caf50, #66bb6a); } .stat-growth { margin-top: 10px; font-size: 14px; color: #666; font-style: italic; } @media (max-width: 768px) { .character-stats-widget { padding: 20px; margin: 10px; } .stats-container { grid-template-columns: 1fr; gap: 15px; } .quick-buttons { gap: 3px; } .level-btn { min-width: 50px; padding: 8px 3px; font-size: 12px; } .character-name { font-size: 24px; } .stat-card .stat-value { font-size: 28px; } } @media (max-width: 480px) { .character-stats-widget { padding: 15px; } .level-btn { min-width: 40px; padding: 6px 2px; font-size: 11px; } .quick-buttons { gap: 2px; } } </style> `; $('head').append(styles); } // 创建角色属性查看器 function createCharacterStatsWidget($container) { var characterId = $container.data('character'); if (!characterId) { $container.html('<div class="error-message">错误:未指定角色ID</div>'); return; } // 创建 Widget HTML 结构 var widgetHTML = ` <div class="character-stats-widget"> <div class="character-header"> <h2 class="character-name">加载中...</h2> <p class="character-description"></p> </div> <div class="level-selector"> <div class="level-display">当前等级: <span class="current-level">1</span></div> <div class="slider-container"> <input type="range" min="1" max="90" value="1" class="level-slider"> </div> <div class="quick-buttons"> <button class="level-btn" data-level="1">1级</button> <button class="level-btn" data-level="10">10级</button> <button class="level-btn" data-level="20">20级</button> <button class="level-btn" data-level="30">30级</button> <button class="level-btn" data-level="40">40级</button> <button class="level-btn" data-level="50">50级</button> <button class="level-btn" data-level="60">60级</button> <button class="level-btn" data-level="70">70级</button> <button class="level-btn" data-level="80">80级</button> <button class="level-btn" data-level="90">90级</button> </div> </div> <div class="stats-container"> <div class="stat-card attack"> <div class="stat-title"> <span>⚔️ 攻击力</span> </div> <div class="stat-value attack-value">-</div> <div class="stat-progress"> <div class="stat-bar attack-bar"></div> </div> <div class="stat-growth">每级成长: <span class="attack-growth">-</span></div> </div> <div class="stat-card health"> <div class="stat-title"> <span>❤️ 生命值</span> </div> <div class="stat-value health-value">-</div> <div class="stat-progress"> <div class="stat-bar health-bar"></div> </div> <div class="stat-growth">每级成长: <span class="health-growth">-</span></div> </div> </div> <div class="loading-message">正在加载角色数据...</div> <div class="error-message" style="display: none;"></div> </div> `; // 插入 HTML $container.html(widgetHTML); // 显示加载状态 var $widget = $container.find('.character-stats-widget'); $widget.find('.level-selector, .stats-container').hide(); $widget.find('.loading-message').show(); // 加载角色数据并初始化 CharacterDataManager.getCharacterData(characterId) .then(function(characterData) { initCharacterStats($widget, characterData); $widget.find('.loading-message').hide(); $widget.find('.level-selector, .stats-container').show(); }) .catch(function(error) { console.error('加载角色数据失败:', error); $widget.find('.loading-message').hide(); $widget.find('.error-message').text('加载角色数据失败: ' + error).show(); }); } // 初始化角色属性显示 function initCharacterStats($widget, characterData) { // 防止重复初始化 if ($widget.data('initialized')) { return; } $widget.data('initialized', true); // 更新角色信息 $widget.find('.character-name').text(characterData.name); $widget.find('.character-description').text(characterData.description); // 生成完整的等级数据 var fullLevelData = generateFullLevelData(characterData); // 获取UI元素 var $levelSlider = $widget.find('.level-slider'); var $currentLevel = $widget.find('.current-level'); var $attackValue = $widget.find('.attack-value'); var $healthValue = $widget.find('.health-value'); var $attackBar = $widget.find('.attack-bar'); var $healthBar = $widget.find('.health-bar'); var $attackGrowth = $widget.find('.attack-growth'); var $healthGrowth = $widget.find('.health-growth'); var $quickButtons = $widget.find('.level-btn'); // 更新显示函数 function updateDisplay(level) { var stats = fullLevelData[level]; $currentLevel.text(level); $attackValue.text(formatNumber(stats.attack)); $healthValue.text(formatNumber(stats.health)); // 显示成长值 if (characterData.stats) { $attackGrowth.text('+' + (characterData.stats.attack_growth || '?')); $healthGrowth.text('+' + (characterData.stats.health_growth || '?')); } // 更新进度条宽度 (基于最大值的百分比) var maxAttack = fullLevelData[90].attack; var maxHealth = fullLevelData[90].health; $attackBar.css('width', (stats.attack / maxAttack) * 100 + '%'); $healthBar.css('width', (stats.health / maxHealth) * 100 + '%'); // 更新快速按钮激活状态 $quickButtons.removeClass('active'); $quickButtons.filter('[data-level="' + level + '"]').addClass('active'); } // 事件绑定 $levelSlider.on('input', function() { updateDisplay(parseInt(this.value)); }); $quickButtons.on('click', function() { var level = parseInt($(this).data('level')); $levelSlider.val(level); updateDisplay(level); }); // 添加键盘支持 $levelSlider.on('keydown', function(e) { var currentValue = parseInt(this.value); switch(e.key) { case 'ArrowLeft': case 'ArrowDown': e.preventDefault(); this.value = Math.max(1, currentValue - 1); updateDisplay(this.value); break; case 'ArrowRight': case 'ArrowUp': e.preventDefault(); this.value = Math.min(90, currentValue + 1); updateDisplay(this.value); break; case 'Home': e.preventDefault(); this.value = 1; updateDisplay(this.value); break; case 'End': e.preventDefault(); this.value = 90; updateDisplay(this.value); break; } }); // 初始显示 updateDisplay(1); } // 生成完整等级数据 function generateFullLevelData(characterData) { var fullData = {}; var baseAttack = (characterData.stats && characterData.stats.base_attack) || 100; var baseHealth = (characterData.stats && characterData.stats.base_health) || 1000; var attackGrowth = (characterData.stats && characterData.stats.attack_growth) || 25; var healthGrowth = (characterData.stats && characterData.stats.health_growth) || 300; // 生成1-90级的完整数据 for (var level = 1; level <= 90; level++) { // 如果有预定义的数据,使用预定义数据,否则计算 if (characterData.levels && characterData.levels[level]) { fullData[level] = characterData.levels[level]; } else { fullData[level] = { attack: baseAttack + attackGrowth * (level - 1), health: baseHealth + healthGrowth * (level - 1) }; } } return fullData; } // 数字格式化函数 function formatNumber(num) { if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } else if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }
返回
MediaWiki:Common.js
。