TierListMaker:修订间差异
来自卡厄思梦境WIKI
无编辑摘要 |
无编辑摘要 |
||
| 第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 { | ||
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 { | ||
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(); | ||
// 注意:不在这里调用 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 => { | ||
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) { | ||
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() { | ||
console.log('初始化拖拽功能...'); | |||
// 使用事件委托方式处理拖拽 | |||
const characterPool = document.getElementById('character-pool'); | |||
const tierRows = document.querySelectorAll('.tier-row'); | |||
// 为现有和未来的avatar元素添加拖拽 | |||
this.makeDraggable(characterPool); | |||
tierRows.forEach(row => this.makeDraggable(row)); | |||
// 为tier行添加拖放事件 | // 为tier行添加拖放事件 | ||
tierRows.forEach(row => { | tierRows.forEach(row => { | ||
if (!row.getAttribute('data-drop-initialized')) { | if (!row.getAttribute('data-drop-initialized')) { | ||
| 第308行: | 第320行: | ||
// 为角色池添加拖放事件 | // 为角色池添加拖放事件 | ||
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/ | 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'; | |||
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 ( | 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'); | ||
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); | ||
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(); | ||
}, | console.log('状态加载完成'); | ||
}, 200); | |||
} catch (e) { | } catch (e) { | ||
| 第730行: | 第752行: | ||
getCharacterId: function(avatar) { | getCharacterId: function(avatar) { | ||
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行: | ||
} | } | ||
const allAvatars = Array.from(document.querySelectorAll('.avatar-frame')); | const allAvatars = Array.from(document.querySelectorAll('.avatar-frame')); | ||
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> | ||