} } // 更新参照物 nextSibling = nodeToUse; } // 4. 清理旧元素 (剩余在 map 里的都是被删掉的) if (existingMap.size > 0) { existingMap.forEach(function(node) { node.remove(); }); } // 5. 恢复锚点位置 if (anchorData) { // 在新 DOM 中找回那个锚点元素 var allBoxes = contentWrapper.querySelectorAll('.box'); var anchorNode = null; for(var k=0; k 1) { window.scrollBy(0, offsetDiff); } } } // 6. 更新序号 reindexBadges(); // 强制释放内存引用 existingMap.clear(); existingMap = null; currentBoxes = null; } // ============================================ // 7. 手动刷新按钮 // ============================================ function handleManualRefresh() { var btn = document.getElementById('manualRefreshBtn'); if (btn.disabled) return; var originalText = btn.innerText; btn.innerText = '刷新中...'; btn.disabled = true; btn.style.opacity = '0.7'; if (autoRefreshTimer) clearTimeout(autoRefreshTimer); fetchContent().then(count => { showToast('已同步最新内容'); }).catch(err => { showToast('刷新失败'); }).finally(() => { btn.innerText = originalText; btn.disabled = false; btn.style.opacity = '1'; startPolling(); }); } // ============================================ // 8. 复制功能 // ============================================ document.addEventListener('click', function(e) { if (e.target && e.target.classList.contains('copyButton')) { var button = e.target; var copyText = button.parentElement.querySelector('.copyText').innerText; if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(copyText).then(() => { showToast('复制成功'); }).catch(err => { fallbackCopy(copyText); }); } else { fallbackCopy(copyText); } } }); function fallbackCopy(text) { var textarea = document.createElement('textarea'); textarea.value = text; textarea.readOnly = true; document.body.appendChild(textarea); textarea.select(); textarea.setSelectionRange(0, 99999); try { document.execCommand('copy'); showToast('复制成功'); } catch (err) {} document.body.removeChild(textarea); } function showToast(message) { var msgBox = document.querySelector('#successMessage'); if (msgBox) { msgBox.innerText = message; msgBox.style.display = 'flex'; if (msgBox.timeoutId) clearTimeout(msgBox.timeoutId); msgBox.timeoutId = setTimeout(() => { msgBox.style.display = 'none'; }, 1500); } }