卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
MediaWiki
查看“︁TierListMaker.js”︁的源代码
←
MediaWiki:TierListMaker.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
(function() { 'use strict'; // 仅在 TierListMaker 页面运行 if (mw.config.get('wgPageName') !== '节奏榜') { return; } // 等待页面加载完成 $(function() { initTierListMaker(); }); function initTierListMaker() { // 添加控制按钮 addControlButtons(); // 初始化拖拽功能 initDragAndDrop(); // 添加样式 addCustomStyles(); // 检查URL中是否有ID参数 checkAndLoadFromURL(); } function addControlButtons() { var $buttonContainer = $('<div>') .attr('id', 'tier-list-controls') .css({ 'margin': '10px 0', 'padding': '10px', 'background': '#f0f0f0', 'border-radius': '5px' }); var $saveButton = $('<button>') .text('保存为PNG') .addClass('tier-list-save-btn') .click(saveTierListAsPNG); var $clearButton = $('<button>') .text('清空所有') .addClass('tier-list-clear-btn') .click(clearAllTiers); var $resetButton = $('<button>') .text('重置') .addClass('tier-list-reset-btn') .click(function() { location.reload(); }); var $saveListButton = $('<button>') .text('保存榜单') .addClass('tier-list-save-list-btn') .click(saveTierListData); var $loadListButton = $('<button>') .text('加载榜单') .addClass('tier-list-load-list-btn') .click(showLoadDialog); var $shareButton = $('<button>') .text('分享榜单') .addClass('tier-list-share-btn') .click(shareTierList); $buttonContainer.append( $saveButton, ' ', $saveListButton, ' ', $loadListButton, ' ', $shareButton, ' ', $clearButton, ' ', $resetButton ); $('.wikitable').before($buttonContainer); } function addCustomStyles() { var styles = ` <style> .tier-list-save-btn, .tier-list-clear-btn, .tier-list-reset-btn, .tier-list-save-list-btn, .tier-list-load-list-btn, .tier-list-share-btn { padding: 8px 16px; margin: 0 5px; font-size: 14px; font-weight: bold; border: none; border-radius: 4px; cursor: pointer; transition: all 0.3s; } .tier-list-save-btn { background: #4CAF50; color: white; } .tier-list-save-btn:hover { background: #45a049; } .tier-list-clear-btn { background: #f44336; color: white; } .tier-list-clear-btn:hover { background: #da190b; } .tier-list-reset-btn { background: #2196F3; color: white; } .tier-list-reset-btn:hover { background: #0b7dda; } .tier-list-save-list-btn { background: #FF9800; color: white; } .tier-list-save-list-btn:hover { background: #e68900; } .tier-list-load-list-btn { background: #9C27B0; color: white; } .tier-list-load-list-btn:hover { background: #7B1FA2; } .tier-list-share-btn { background: #00BCD4; color: white; } .tier-list-share-btn:hover { background: #0097A7; } .wikitable td { min-height: 120px; min-width: 300px; padding: 10px; vertical-align: top; position: relative; } .tier-row-drop-zone { border: 2px dashed transparent; transition: all 0.3s; } .tier-row-drop-zone.drag-over { border-color: #2196F3; background-color: rgba(33, 150, 243, 0.1); } .avatar-frame { cursor: move; transition: transform 0.2s, opacity 0.2s; user-select: none; } .avatar-frame:hover { transform: scale(1.05); } .avatar-frame.dragging { opacity: 0.5; } .avatar-frame.in-tier { margin: 5px; } #avatar-pool { border: 2px solid #ddd; padding: 10px; margin: 10px 0; border-radius: 5px; background: #fafafa; min-height: 150px; } #avatar-pool-title { font-size: 16px; font-weight: bold; margin-bottom: 10px; color: #333; } .tier-dialog-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); z-index: 9998; display: flex; align-items: center; justify-content: center; } .tier-dialog { background: white; padding: 30px; border-radius: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); max-width: 500px; width: 90%; z-index: 9999; } .tier-dialog h3 { margin-top: 0; margin-bottom: 20px; color: #333; } .tier-dialog label { display: block; margin-bottom: 8px; font-weight: bold; color: #555; } .tier-dialog input[type="text"] { width: 100%; padding: 10px; border: 2px solid #ddd; border-radius: 5px; font-size: 14px; box-sizing: border-box; margin-bottom: 15px; } .tier-dialog input[type="text"]:focus { outline: none; border-color: #2196F3; } .tier-dialog-buttons { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; } .tier-dialog-btn { padding: 10px 20px; border: none; border-radius: 5px; font-size: 14px; font-weight: bold; cursor: pointer; transition: all 0.3s; } .tier-dialog-btn-primary { background: #2196F3; color: white; } .tier-dialog-btn-primary:hover { background: #0b7dda; } .tier-dialog-btn-secondary { background: #ddd; color: #333; } .tier-dialog-btn-secondary:hover { background: #ccc; } .tier-id-display { background: #f0f8ff; padding: 15px; border-radius: 5px; border: 2px solid #2196F3; margin: 15px 0; word-break: break-all; } .tier-id-label { font-weight: bold; color: #2196F3; margin-bottom: 5px; } .tier-id-value { font-family: 'Courier New', monospace; font-size: 16px; color: #333; user-select: all; } .tier-url-display { background: #f0f8ff; padding: 15px; border-radius: 5px; border: 2px solid #00BCD4; margin: 15px 0; word-break: break-all; } .copy-btn { background: #4CAF50; color: white; padding: 5px 15px; border: none; border-radius: 3px; cursor: pointer; font-size: 12px; margin-left: 10px; } .copy-btn:hover { background: #45a049; } .success-message { color: #4CAF50; font-weight: bold; margin-top: 10px; } </style> `; $('head').append(styles); } function initDragAndDrop() { // 创建头像池容器 var $avatarPool = $('<div>') .attr('id', 'avatar-pool') .addClass('tier-row-drop-zone'); var $poolTitle = $('<div>') .attr('id', 'avatar-pool-title') .text('角色池(拖动到上方表格)'); $avatarPool.append($poolTitle); // 将所有头像移动到头像池 var $avatars = $('.avatar-frame'); $avatars.each(function() { $(this).addClass('avatar-item').appendTo($avatarPool); }); $('.wikitable').after($avatarPool); // 为表格单元格添加drop-zone类 $('.wikitable td').addClass('tier-row-drop-zone'); // 初始化所有头像的拖拽 initAvatarDrag(); // 初始化所有drop zone initDropZones(); } function initAvatarDrag() { $('.avatar-frame').each(function() { var $avatar = $(this); $avatar.attr('draggable', 'true'); $avatar.on('dragstart', function(e) { $(this).addClass('dragging'); e.originalEvent.dataTransfer.effectAllowed = 'move'; e.originalEvent.dataTransfer.setData('text/html', this.outerHTML); }); $avatar.on('dragend', function(e) { $(this).removeClass('dragging'); }); }); } function initDropZones() { $('.tier-row-drop-zone').each(function() { var $zone = $(this); $zone.on('dragover', function(e) { e.preventDefault(); e.originalEvent.dataTransfer.dropEffect = 'move'; $(this).addClass('drag-over'); }); $zone.on('dragleave', function(e) { $(this).removeClass('drag-over'); }); $zone.on('drop', function(e) { e.preventDefault(); $(this).removeClass('drag-over'); var $dragging = $('.avatar-frame.dragging'); if ($dragging.length) { // 移动现有元素 $dragging.removeClass('dragging'); // 如果是在tier中,添加样式 if ($(this).hasClass('wikitable')) { $dragging.addClass('in-tier'); } else if ($(this).attr('id') === 'avatar-pool') { $dragging.removeClass('in-tier'); } else { $dragging.addClass('in-tier'); } $(this).append($dragging); } }); }); } function clearAllTiers() { if (!confirm('确定要清空所有分级吗?')) { return; } // 将所有tier中的头像移回头像池 $('.wikitable td .avatar-frame').each(function() { $(this).removeClass('in-tier'); $('#avatar-pool').append($(this)); }); } // 保存榜单数据 function saveTierListData() { var tierData = collectTierData(); if (tierData.tiers.length === 0 && tierData.pool.length === $('.avatar-frame').length) { alert('您还没有放置任何角色到榜单中!'); return; } var listId = generateUniqueId(); var timestamp = new Date().toISOString(); var saveData = { id: listId, timestamp: timestamp, data: tierData }; // 保存到 localStorage localStorage.setItem('tierlist_' + listId, JSON.stringify(saveData)); // 显示保存成功对话框 showSaveSuccessDialog(listId); } // 收集榜单数据 function collectTierData() { var data = { tiers: [], pool: [] }; // 收集表格中的数据 $('.wikitable tr').each(function(rowIndex) { var $cells = $(this).find('td'); if ($cells.length > 0) { var tierName = $cells.eq(0).text().trim(); var avatars = []; $cells.eq(1).find('.avatar-frame').each(function() { var avatarId = getAvatarIdentifier($(this)); if (avatarId) { avatars.push(avatarId); } }); if (avatars.length > 0) { data.tiers.push({ name: tierName, avatars: avatars }); } } }); // 收集头像池中的数据 $('#avatar-pool .avatar-frame').each(function() { var avatarId = getAvatarIdentifier($(this)); if (avatarId) { data.pool.push(avatarId); } }); return data; } // 获取头像的唯一标识符 function getAvatarIdentifier($avatar) { // 尝试多种方式获取头像标识 var identifier = null; // 方法1: 通过图片src var $img = $avatar.find('img'); if ($img.length > 0) { identifier = $img.attr('src'); } // 方法2: 通过data属性 if (!identifier && $avatar.attr('data-avatar-id')) { identifier = $avatar.attr('data-avatar-id'); } // 方法3: 通过alt或title if (!identifier && $img.attr('alt')) { identifier = $img.attr('alt'); } // 方法4: 通过完整HTML(作为后备) if (!identifier) { identifier = $avatar.prop('outerHTML'); } return identifier; } // 生成唯一ID function generateUniqueId() { var timestamp = Date.now().toString(36); var randomStr = Math.random().toString(36).substr(2, 9); return timestamp + randomStr; } // 显示保存成功对话框 function showSaveSuccessDialog(listId) { var shareUrl = window.location.href.split('?')[0] + '?tierid=' + listId; var $overlay = $('<div>').addClass('tier-dialog-overlay'); var $dialog = $('<div>').addClass('tier-dialog'); var $title = $('<h3>').text('榜单保存成功!'); var $idDisplay = $('<div>').addClass('tier-id-display'); var $idLabel = $('<div>').addClass('tier-id-label').text('榜单ID:'); var $idValue = $('<div>').addClass('tier-id-value').text(listId); var $copyIdBtn = $('<button>').addClass('copy-btn').text('复制ID') .click(function() { copyToClipboard(listId); $(this).text('已复制!').css('background', '#4CAF50'); setTimeout(() => { $(this).text('复制ID').css('background', ''); }, 2000); }); $idDisplay.append($idLabel, $idValue, $copyIdBtn); var $urlDisplay = $('<div>').addClass('tier-url-display'); var $urlLabel = $('<div>').addClass('tier-id-label').text('分享链接:'); var $urlValue = $('<div>').addClass('tier-id-value').text(shareUrl); var $copyUrlBtn = $('<button>').addClass('copy-btn').text('复制链接') .click(function() { copyToClipboard(shareUrl); $(this).text('已复制!').css('background', '#4CAF50'); setTimeout(() => { $(this).text('复制链接').css('background', ''); }, 2000); }); $urlDisplay.append($urlLabel, $urlValue, $copyUrlBtn); var $info = $('<p>').css({'color': '#666', 'margin': '15px 0'}) .text('保存的榜单将在本地存储,您可以通过ID或链接访问。'); var $buttons = $('<div>').addClass('tier-dialog-buttons'); var $closeBtn = $('<button>') .addClass('tier-dialog-btn tier-dialog-btn-primary') .text('关闭') .click(function() { $overlay.remove(); }); $buttons.append($closeBtn); $dialog.append($title, $idDisplay, $urlDisplay, $info, $buttons); $overlay.append($dialog); $('body').append($overlay); } // 显示加载对话框 function showLoadDialog() { var $overlay = $('<div>').addClass('tier-dialog-overlay'); var $dialog = $('<div>').addClass('tier-dialog'); var $title = $('<h3>').text('加载榜单'); var $label = $('<label>').text('请输入榜单ID:'); var $input = $('<input>') .attr('type', 'text') .attr('placeholder', '输入榜单ID') .attr('id', 'tier-id-input'); var $errorMsg = $('<div>') .css({'color': '#f44336', 'margin-top': '10px', 'display': 'none'}) .attr('id', 'load-error-msg'); var $buttons = $('<div>').addClass('tier-dialog-buttons'); var $loadBtn = $('<button>') .addClass('tier-dialog-btn tier-dialog-btn-primary') .text('加载') .click(function() { var listId = $input.val().trim(); if (!listId) { $errorMsg.text('请输入榜单ID!').show(); return; } if (loadTierListData(listId)) { $overlay.remove(); } else { $errorMsg.text('未找到该榜单,请检查ID是否正确!').show(); } }); var $cancelBtn = $('<button>') .addClass('tier-dialog-btn tier-dialog-btn-secondary') .text('取消') .click(function() { $overlay.remove(); }); $buttons.append($cancelBtn, $loadBtn); $dialog.append($title, $label, $input, $errorMsg, $buttons); $overlay.append($dialog); $('body').append($overlay); // 聚焦输入框 setTimeout(() => $input.focus(), 100); // 支持回车键加载 $input.on('keypress', function(e) { if (e.which === 13) { $loadBtn.click(); } }); } // 加载榜单数据 function loadTierListData(listId) { var savedData = localStorage.getItem('tierlist_' + listId); if (!savedData) { return false; } try { var saveData = JSON.parse(savedData); applyTierData(saveData.data); // 显示加载成功提示 showNotification('榜单加载成功!', 'success'); return true; } catch (e) { console.error('加载榜单失败:', e); return false; } } // 应用榜单数据 function applyTierData(tierData) { // 首先清空所有层级 $('.wikitable td .avatar-frame').each(function() { $(this).removeClass('in-tier'); $('#avatar-pool').append($(this)); }); // 应用tier数据 tierData.tiers.forEach(function(tier) { var $targetCell = null; // 查找对应的tier单元格 $('.wikitable tr').each(function() { var $cells = $(this).find('td'); if ($cells.length > 0) { var tierName = $cells.eq(0).text().trim(); if (tierName === tier.name) { $targetCell = $cells.eq(1); return false; } } }); if ($targetCell) { tier.avatars.forEach(function(avatarId) { var $avatar = findAvatarByIdentifier(avatarId); if ($avatar) { $avatar.addClass('in-tier'); $targetCell.append($avatar); } }); } }); } // 根据标识符查找头像 function findAvatarByIdentifier(identifier) { var $found = null; $('.avatar-frame').each(function() { var $avatar = $(this); var currentId = getAvatarIdentifier($avatar); if (currentId === identifier) { $found = $avatar; return false; } }); return $found; } // 分享榜单 function shareTierList() { var tierData = collectTierData(); if (tierData.tiers.length === 0 && tierData.pool.length === $('.avatar-frame').length) { alert('您还没有放置任何角色到榜单中!'); return; } // 检查是否已经保存 var currentUrl = window.location.href; var urlParams = new URLSearchParams(window.location.search); var existingId = urlParams.get('tierid'); if (existingId) { // 已有ID,直接分享 var shareUrl = window.location.href.split('?')[0] + '?tierid=' + existingId; showShareDialog(shareUrl, existingId); } else { // 先保存再分享 var listId = generateUniqueId(); var timestamp = new Date().toISOString(); var saveData = { id: listId, timestamp: timestamp, data: tierData }; localStorage.setItem('tierlist_' + listId, JSON.stringify(saveData)); var shareUrl = window.location.href.split('?')[0] + '?tierid=' + listId; showShareDialog(shareUrl, listId); } } // 显示分享对话框 function showShareDialog(shareUrl, listId) { var $overlay = $('<div>').addClass('tier-dialog-overlay'); var $dialog = $('<div>').addClass('tier-dialog'); var $title = $('<h3>').text('分享榜单'); var $urlDisplay = $('<div>').addClass('tier-url-display'); var $urlLabel = $('<div>').addClass('tier-id-label').text('分享链接:'); var $urlValue = $('<div>').addClass('tier-id-value').text(shareUrl); var $copyUrlBtn = $('<button>').addClass('copy-btn').text('复制链接') .click(function() { copyToClipboard(shareUrl); $(this).text('已复制!').css('background', '#4CAF50'); setTimeout(() => { $(this).text('复制链接').css('background', ''); }, 2000); }); $urlDisplay.append($urlLabel, $urlValue, $copyUrlBtn); var $idDisplay = $('<div>').addClass('tier-id-display'); var $idLabel = $('<div>').addClass('tier-id-label').text('榜单ID:'); var $idValue = $('<div>').addClass('tier-id-value').text(listId); var $copyIdBtn = $('<button>').addClass('copy-btn').text('复制ID') .click(function() { copyToClipboard(listId); $(this).text('已复制!').css('background', '#4CAF50'); setTimeout(() => { $(this).text('复制ID').css('background', ''); }, 2000); }); $idDisplay.append($idLabel, $idValue, $copyIdBtn); var $info = $('<p>').css({'color': '#666', 'margin': '15px 0'}) .text('将此链接分享给其他人,他们可以查看您的榜单!'); var $buttons = $('<div>').addClass('tier-dialog-buttons'); var $closeBtn = $('<button>') .addClass('tier-dialog-btn tier-dialog-btn-primary') .text('关闭') .click(function() { $overlay.remove(); }); $buttons.append($closeBtn); $dialog.append($title, $urlDisplay, $idDisplay, $info, $buttons); $overlay.append($dialog); $('body').append($overlay); } // 检查URL并加载榜单 function checkAndLoadFromURL() { var urlParams = new URLSearchParams(window.location.search); var tierid = urlParams.get('tierid'); if (tierid) { setTimeout(function() { if (loadTierListData(tierid)) { showNotification('已加载分享的榜单!ID: ' + tierid, 'success'); } else { showNotification('无法加载榜单,ID可能无效或已过期', 'error'); } }, 500); } } // 复制到剪贴板 function copyToClipboard(text) { if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text); } else { // 后备方案 var $temp = $('<textarea>'); $('body').append($temp); $temp.val(text).select(); document.execCommand('copy'); $temp.remove(); } } // 显示通知 function showNotification(message, type) { var bgColor = type === 'success' ? '#4CAF50' : '#f44336'; var $notification = $('<div>') .css({ 'position': 'fixed', 'top': '20px', 'right': '20px', 'background': bgColor, 'color': 'white', 'padding': '15px 25px', 'border-radius': '5px', 'box-shadow': '0 4px 12px rgba(0,0,0,0.3)', 'z-index': 10000, 'font-size': '14px', 'font-weight': 'bold', 'animation': 'slideIn 0.3s ease-out' }) .text(message); $('body').append($notification); setTimeout(function() { $notification.fadeOut(300, function() { $(this).remove(); }); }, 3000); } function saveTierListAsPNG() { // 检查是否已加载html2canvas库 if (typeof html2canvas === 'undefined') { loadHtml2Canvas(function() { captureTierList(); }); } else { captureTierList(); } } function loadHtml2Canvas(callback) { mw.loader.using('jquery', function() { $.getScript('https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js') .done(function() { callback(); }) .fail(function() { alert('加载截图库失败,请检查网络连接'); }); }); } function captureTierList() { var $table = $('.wikitable'); if ($table.length === 0) { alert('未找到表格'); return; } // 显示加载提示 var $loading = $('<div>') .css({ 'position': 'fixed', 'top': '50%', 'left': '50%', 'transform': 'translate(-50%, -50%)', 'background': 'rgba(0,0,0,0.8)', 'color': 'white', 'padding': '20px 40px', 'border-radius': '10px', 'z-index': 9999, 'font-size': '18px' }) .text('正在生成图片...') .appendTo('body'); html2canvas($table[0], { backgroundColor: '#ffffff', scale: 2, logging: false, useCORS: true, allowTaint: true }).then(function(canvas) { $loading.remove(); // 转换为blob并下载 canvas.toBlob(function(blob) { var url = URL.createObjectURL(blob); var link = document.createElement('a'); var timestamp = new Date().toISOString().slice(0,19).replace(/:/g,'-'); link.download = 'tier-list-' + timestamp + '.png'; link.href = url; link.click(); URL.revokeObjectURL(url); }); }).catch(function(error) { $loading.remove(); console.error('截图失败:', error); alert('生成图片失败,请重试'); }); } })();
返回
MediaWiki:TierListMaker.js
。