微件

TierListMaker:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
无编辑摘要
律Rhyme留言 | 贡献
无编辑摘要
第117行: 第117行:
}
}


/* 编辑模式下的样式 */
.tier-header.editable {
.tier-header.editable {
     cursor: pointer;
     cursor: pointer;
第156行: 第155行:
}
}


/* 颜色选择器容器 */
.color-picker-popup {
.color-picker-popup {
     position: fixed;
     position: fixed;
第222行: 第220行:
}
}


/* 确保avatar-frame正确显示 */
.avatar-frame {
.avatar-frame {
     display: inline-block;
     display: inline-block;
第245行: 第242行:
         sourceContainer: null,
         sourceContainer: null,
         editMode: false,
         editMode: false,
        initRetryCount: 0,
        maxRetries: 10,
          
          
         init: function() {
         init: function() {
第251行: 第250行:
                 document.addEventListener('DOMContentLoaded', () => this.setup());
                 document.addEventListener('DOMContentLoaded', () => this.setup());
             } else {
             } else {
                 setTimeout(() => this.setup(), 100);
                 this.setup();
             }
             }
         },
         },
          
          
         setup: function() {
         setup: function() {
             this.cleanupContainers(); // 清理可能存在的空元素
            // 检查角色池是否已加载
            const characterPool = document.getElementById('character-pool');
            const avatars = characterPool ? characterPool.querySelectorAll('.avatar-frame') : [];
           
            if (avatars.length === 0 && this.initRetryCount < this.maxRetries) {
                // 角色还未加载,等待后重试
                this.initRetryCount++;
                console.log('等待角色加载...', this.initRetryCount);
                setTimeout(() => this.setup(), 300);
                return;
            }
           
            if (avatars.length === 0) {
                console.warn('未找到角色,可能加载失败');
            }
           
            console.log('找到角色数量:', avatars.length);
           
             this.cleanupContainers();
             this.initDragAndDrop();
             this.initDragAndDrop();
             this.initButtons();
             this.initButtons();
             this.loadState();
             // 注意:不在这里调用 loadState()
         },
         },
          
          
第266行: 第283行:
             const containers = document.querySelectorAll('.tier-row, #character-pool');
             const containers = document.querySelectorAll('.tier-row, #character-pool');
             containers.forEach(container => {
             containers.forEach(container => {
                // 移除所有空的文本节点和空div
                 const children = Array.from(container.childNodes);
                 const children = Array.from(container.childNodes);
                 children.forEach(child => {
                 children.forEach(child => {
第272行: 第288行:
                         container.removeChild(child);
                         container.removeChild(child);
                     } else if (child.nodeType === Node.ELEMENT_NODE) {
                     } else if (child.nodeType === Node.ELEMENT_NODE) {
                        // 移除空的div或没有avatar-frame类的空元素
                         if (!child.classList.contains('avatar-frame') &&  
                         if (!child.classList.contains('avatar-frame') &&  
                             !child.querySelector('.avatar-frame') &&  
                             !child.querySelector('.avatar-frame') &&  
第284行: 第299行:
          
          
         initDragAndDrop: function() {
         initDragAndDrop: function() {
             const avatars = document.querySelectorAll('.avatar-frame');
             console.log('初始化拖拽功能...');
              
              
             avatars.forEach(avatar => {
             // 使用事件委托方式处理拖拽
                if (!avatar.getAttribute('data-drag-initialized')) {
            const characterPool = document.getElementById('character-pool');
                    avatar.setAttribute('draggable', 'true');
            const tierRows = document.querySelectorAll('.tier-row');
                    avatar.setAttribute('data-drag-initialized', 'true');
           
                   
            // 为现有和未来的avatar元素添加拖拽
                    avatar.addEventListener('dragstart', (e) => this.handleDragStart(e, avatar));
            this.makeDraggable(characterPool);
                    avatar.addEventListener('dragend', (e) => this.handleDragEnd(e, avatar));
            tierRows.forEach(row => this.makeDraggable(row));
                }
            });
              
              
             // 为tier行添加拖放事件
             // 为tier行添加拖放事件
            const tierRows = document.querySelectorAll('.tier-row');
             tierRows.forEach(row => {
             tierRows.forEach(row => {
                 if (!row.getAttribute('data-drop-initialized')) {
                 if (!row.getAttribute('data-drop-initialized')) {
第308行: 第320行:
              
              
             // 为角色池添加拖放事件
             // 为角色池添加拖放事件
            const characterPool = document.getElementById('character-pool');
             if (characterPool && !characterPool.getAttribute('data-drop-initialized')) {
             if (characterPool && !characterPool.getAttribute('data-drop-initialized')) {
                 characterPool.setAttribute('data-drop-initialized', 'true');
                 characterPool.setAttribute('data-drop-initialized', 'true');
第315行: 第326行:
                 characterPool.addEventListener('dragleave', (e) => this.handleDragLeave(e, characterPool));
                 characterPool.addEventListener('dragleave', (e) => this.handleDragLeave(e, characterPool));
             }
             }
        },
       
        // 使容器内的所有avatar可拖拽
        makeDraggable: function(container) {
            if (!container) return;
           
            const avatars = container.querySelectorAll('.avatar-frame');
            avatars.forEach(avatar => {
                if (!avatar.getAttribute('data-drag-initialized')) {
                    avatar.setAttribute('draggable', 'true');
                    avatar.setAttribute('data-drag-initialized', 'true');
                   
                    avatar.addEventListener('dragstart', (e) => this.handleDragStart(e, avatar));
                    avatar.addEventListener('dragend', (e) => this.handleDragEnd(e, avatar));
                   
                    console.log('已设置拖拽:', avatar);
                }
            });
         },
         },
          
          
         handleDragStart: function(e, element) {
         handleDragStart: function(e, element) {
            console.log('开始拖拽:', element);
             this.draggedElement = element;
             this.draggedElement = element;
             this.sourceContainer = element.parentElement;
             this.sourceContainer = element.parentElement;
             element.classList.add('dragging');
             element.classList.add('dragging');
            element.style.opacity = '0.5';
             e.dataTransfer.effectAllowed = 'move';
             e.dataTransfer.effectAllowed = 'move';
             e.dataTransfer.setData('text/plain', element.getAttribute('data-character-id') || 'drag');
             e.dataTransfer.setData('text/html', element.innerHTML);
         },
         },
          
          
         handleDragEnd: function(e, element) {
         handleDragEnd: function(e, element) {
            console.log('结束拖拽:', element);
             element.classList.remove('dragging');
             element.classList.remove('dragging');
            element.style.opacity = '1';
              
              
            // 移除所有drag-over类
             document.querySelectorAll('.drag-over').forEach(el => {
             document.querySelectorAll('.drag-over').forEach(el => {
                 el.classList.remove('drag-over');
                 el.classList.remove('drag-over');
             });
             });
              
              
            // 清理可能产生的空元素
             this.cleanupContainers();
             this.cleanupContainers();
           
            // 保存状态
             this.saveState();
             this.saveState();
              
              
第357行: 第386行:
          
          
         handleDragLeave: function(e, element) {
         handleDragLeave: function(e, element) {
             if (e.target === element) {
            const rect = element.getBoundingClientRect();
            const x = e.clientX;
            const y = e.clientY;
           
             if (x <= rect.left || x >= rect.right || y <= rect.top || y >= rect.bottom) {
                 element.classList.remove('drag-over');
                 element.classList.remove('drag-over');
             }
             }
第365行: 第398行:
             e.preventDefault();
             e.preventDefault();
             e.stopPropagation();
             e.stopPropagation();
           
            console.log('放置到:', element);
              
              
             element.classList.remove('drag-over');
             element.classList.remove('drag-over');
              
              
             if (this.draggedElement && this.draggedElement.parentElement !== element) {
             if (this.draggedElement && this.draggedElement.parentElement !== element) {
                // 从原位置移除
                 if (this.draggedElement.parentElement) {
                 if (this.draggedElement.parentElement) {
                     this.draggedElement.parentElement.removeChild(this.draggedElement);
                     this.draggedElement.parentElement.removeChild(this.draggedElement);
                 }
                 }
                  
                  
                // 添加到新位置
                 element.appendChild(this.draggedElement);
                 element.appendChild(this.draggedElement);
                  
                  
                // 确保图片透明度正常
                 const img = this.draggedElement.querySelector('img');
                 const img = this.draggedElement.querySelector('img');
                 if (img) {
                 if (img) {
第383行: 第415行:
                 }
                 }
                  
                  
                // 清理空元素
                 this.cleanupContainers();
                 this.cleanupContainers();
               
                console.log('放置成功');
             }
             }
              
              
第423行: 第456行:
                 table.classList.add('edit-mode');
                 table.classList.add('edit-mode');
                  
                  
                // 为所有tier header添加编辑功能
                 document.querySelectorAll('.tier-header').forEach(header => {
                 document.querySelectorAll('.tier-header').forEach(header => {
                     header.classList.add('editable');
                     header.classList.add('editable');
第455行: 第487行:
             const currentBgColor = header.style.backgroundColor || '#000000';
             const currentBgColor = header.style.backgroundColor || '#000000';
              
              
            // 创建弹窗
             const overlay = document.createElement('div');
             const overlay = document.createElement('div');
             overlay.className = 'overlay';
             overlay.className = 'overlay';
第490行: 第521行:
                     header.style.backgroundColor = newColor;
                     header.style.backgroundColor = newColor;
                      
                      
                    // 重新添加删除按钮
                     const newDeleteBtn = document.createElement('button');
                     const newDeleteBtn = document.createElement('button');
                     newDeleteBtn.className = 'delete-row-btn';
                     newDeleteBtn.className = 'delete-row-btn';
第500行: 第530行:
                     header.appendChild(newDeleteBtn);
                     header.appendChild(newDeleteBtn);
                      
                      
                    // 更新对应的tier-row
                     const row = header.parentElement.querySelector('.tier-row');
                     const row = header.parentElement.querySelector('.tier-row');
                     if (row) {
                     if (row) {
第557行: 第586行:
             tbody.appendChild(newRow);
             tbody.appendChild(newRow);
              
              
            // 为新行添加拖放事件
             const newTierRow = newRow.querySelector('.tier-row');
             const newTierRow = newRow.querySelector('.tier-row');
             newTierRow.setAttribute('data-drop-initialized', 'true');
             newTierRow.setAttribute('data-drop-initialized', 'true');
第564行: 第592行:
             newTierRow.addEventListener('dragleave', (e) => this.handleDragLeave(e, newTierRow));
             newTierRow.addEventListener('dragleave', (e) => this.handleDragLeave(e, newTierRow));
              
              
            // 如果在编辑模式下,添加编辑功能
             if (this.editMode) {
             if (this.editMode) {
                 const header = newRow.querySelector('.tier-header');
                 const header = newRow.querySelector('.tier-header');
第593行: 第620行:
             const pool = document.getElementById('character-pool');
             const pool = document.getElementById('character-pool');
              
              
            // 将角色移回角色池
             avatars.forEach(avatar => {
             avatars.forEach(avatar => {
                 pool.appendChild(avatar);
                 pool.appendChild(avatar);
             });
             });
              
              
            // 删除行
             row.remove();
             row.remove();
              
              
            // 清理空元素
             this.cleanupContainers();
             this.cleanupContainers();
           
             this.saveState();
             this.saveState();
         },
         },
第613行: 第636行:
             };
             };
              
              
            // 保存表格行信息
             document.querySelectorAll('#tierlist-table tbody tr').forEach(row => {
             document.querySelectorAll('#tierlist-table tbody tr').forEach(row => {
                 const header = row.querySelector('.tier-header');
                 const header = row.querySelector('.tier-header');
第636行: 第658行:
             });
             });
              
              
            // 保存角色池信息
             const pool = document.getElementById('character-pool');
             const pool = document.getElementById('character-pool');
             if (pool) {
             if (pool) {
第649行: 第670行:
             try {
             try {
                 localStorage.setItem('tierlist-state', JSON.stringify(state));
                 localStorage.setItem('tierlist-state', JSON.stringify(state));
                console.log('状态已保存');
             } catch (e) {
             } catch (e) {
                 console.warn('无法保存状态:', e);
                 console.warn('无法保存状态:', e);
第657行: 第679行:
             try {
             try {
                 const stateJson = localStorage.getItem('tierlist-state');
                 const stateJson = localStorage.getItem('tierlist-state');
                 if (!stateJson) return;
                 if (!stateJson) {
                    console.log('没有保存的状态');
                    return;
                }
                  
                  
                 const state = JSON.parse(stateJson);
                 const state = JSON.parse(stateJson);
                console.log('加载保存的状态:', state);
                  
                  
                // 先清空所有行(保留第一行作为模板)
                 const tbody = document.querySelector('#tierlist-table tbody');
                 const tbody = document.querySelector('#tierlist-table tbody');
                 const rows = Array.from(tbody.querySelectorAll('tr'));
                 const rows = Array.from(tbody.querySelectorAll('tr'));
                  
                  
                // 恢复表格结构
                 if (state.rows && state.rows.length > 0) {
                 if (state.rows && state.rows.length > 0) {
                     rows.forEach((row, index) => {
                     rows.forEach((row, index) => {
第682行: 第706行:
                                 if (tierRow) {
                                 if (tierRow) {
                                     tierRow.setAttribute('data-tier', savedRow.name);
                                     tierRow.setAttribute('data-tier', savedRow.name);
                                     tierRow.innerHTML = ''; // 清空内容
                                     tierRow.innerHTML = '';
                                 }
                                 }
                             }
                             }
第688行: 第712行:
                     });
                     });
                      
                      
                    // 如果保存的行数多于当前行数,添加新行
                     for (let i = rows.length; i < state.rows.length; i++) {
                     for (let i = rows.length; i < state.rows.length; i++) {
                         const savedRow = state.rows[i];
                         const savedRow = state.rows[i];
第706行: 第729行:
                 }
                 }
                  
                  
                // 恢复角色位置
                 setTimeout(() => {
                 setTimeout(() => {
                     state.rows.forEach((rowData, index) => {
                     state.rows.forEach((rowData, index) => {
第720行: 第742行:
                     });
                     });
                      
                      
                    // 清理可能产生的空元素
                     this.cleanupContainers();
                     this.cleanupContainers();
                 }, 100);
                    console.log('状态加载完成');
                 }, 200);
                  
                  
             } catch (e) {
             } catch (e) {
第730行: 第752行:
          
          
         getCharacterId: function(avatar) {
         getCharacterId: function(avatar) {
            // 尝试多种方式获取角色ID
             const img = avatar.querySelector('img');
             const img = avatar.querySelector('img');
             if (img) {
             if (img) {
第776行: 第797行:
             const originalPoolDisplay = poolContainer ? poolContainer.style.display : '';
             const originalPoolDisplay = poolContainer ? poolContainer.style.display : '';
              
              
            // 隐藏编辑按钮
             const deleteButtons = document.querySelectorAll('.delete-row-btn');
             const deleteButtons = document.querySelectorAll('.delete-row-btn');
             deleteButtons.forEach(btn => btn.style.display = 'none');
             deleteButtons.forEach(btn => btn.style.display = 'none');
第819行: 第839行:
             }
             }
              
              
            // 收集所有avatar元素
             const allAvatars = Array.from(document.querySelectorAll('.avatar-frame'));
             const allAvatars = Array.from(document.querySelectorAll('.avatar-frame'));
              
              
            // 清空所有tier行
             document.querySelectorAll('.tier-row').forEach(row => {
             document.querySelectorAll('.tier-row').forEach(row => {
                 row.innerHTML = '';
                 row.innerHTML = '';
             });
             });
              
              
            // 清空角色池
             pool.innerHTML = '';
             pool.innerHTML = '';
              
              
            // 将所有角色添加回角色池
             allAvatars.forEach(avatar => {
             allAvatars.forEach(avatar => {
                 pool.appendChild(avatar);
                 pool.appendChild(avatar);
第839行: 第855行:
             });
             });
              
              
            // 清理空元素
             this.cleanupContainers();
             this.cleanupContainers();
              
              
            // 清除保存的状态
             try {
             try {
                 localStorage.removeItem('tierlist-state');
                 localStorage.removeItem('tierlist-state');
                console.log('状态已清除');
             } catch (e) {
             } catch (e) {
                 console.warn('无法清除状态:', e);
                 console.warn('无法清除状态:', e);
             }
             }
           
            alert('重置完成!');
         }
         }
     };
     };
      
      
    // 标记已初始化
     window.TierlistMakerInitialized = true;
     window.TierlistMakerInitialized = true;
     window.TierlistMaker = TierlistMaker;
     window.TierlistMaker = TierlistMaker;
      
      
    // 自动初始化
     TierlistMaker.init();
     TierlistMaker.init();
   
    // 添加手动加载状态的按钮功能
    window.loadTierlistState = function() {
        if (window.TierlistMaker) {
            window.TierlistMaker.loadState();
        }
    };
})();
})();
</script>
</script>
</includeonly>
</includeonly>

2025年10月20日 (一) 21:50的版本