结束。
// 由于篇幅限制,这里不再重复粘贴,请将之前完整版的这些函数复制进来即可,它们没有改动。
// 注意:在 initWebSocket 之前添加 window.popstate 等启动代码,具体如下:
// WebSocket
function initWebSocket() {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
ws = new WebSocket(`${protocol}//${window.location.host}?userId=${USER_ID}`);
ws.onopen = () => { console.log('WebSocket 已连接'); if (reconnectTimer) clearTimeout(reconnectTimer); };
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
if (data.type === 'data_changed') {
if (!isReloading) { isReloading = true; setTimeout(async () => { await handleRouting(); isReloading = false; }, 100); }
} else if (data.type === 'danmaku') {
addMessageBubble(data.message, data.level, data.userName, data.userAvatar);
} else if (data.type === 'offline_messages') {
data.messages.forEach(msg => addMessageBubble(msg.message, msg.type));
}
} catch (e) { console.error('WebSocket 消息解析失败', e); }
};
ws.onclose = () => { console.log('WebSocket 断开,重连...'); reconnectTimer = setTimeout(initWebSocket, 3000); };
ws.onerror = (err) => { console.error('WebSocket 错误', err); };
}
// 启动
API.syncUserInfo();
initWebSocket();
window.addEventListener('popstate', () => handleRouting());
document.getElementById('saveRuleBtn')?.addEventListener('click', saveRule);
document.querySelectorAll('.close-rule-modal').forEach(b => b.addEventListener('click', closeRuleModal));
document.querySelectorAll('.close-batch-result').forEach(b => b.addEventListener('click', closeBatchResult));
handleRouting();
})();