class UIManager { constructor() { // 延迟初始化,确保DOM已加载 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => this.init()); } else { // 如果DOM已经加载完成,则立即初始化 this.init(); } } init() { console.log('初始化UI管理器...'); // UI elements this.settingsPanel = document.getElementById('settingsPanel'); this.settingsToggle = document.getElementById('settingsToggle'); this.closeSettings = document.getElementById('closeSettings'); this.themeToggle = document.getElementById('themeToggle'); this.toastContainer = document.getElementById('toastContainer'); // 验证关键元素是否存在 if (!this.themeToggle) { console.error('主题切换按钮未找到!'); return; } if (!this.toastContainer) { console.error('Toast容器未找到!'); // 尝试创建Toast容器 this.toastContainer = this.createToastContainer(); } // Check for preferred color scheme this.checkPreferredColorScheme(); // Initialize event listeners this.setupEventListeners(); console.log('UI管理器初始化完成'); } createToastContainer() { console.log('创建Toast容器'); const container = document.createElement('div'); container.id = 'toastContainer'; container.className = 'toast-container'; document.body.appendChild(container); return container; } checkPreferredColorScheme() { const savedTheme = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); if (savedTheme) { this.setTheme(savedTheme === 'dark'); } else { this.setTheme(prefersDark.matches); } prefersDark.addEventListener('change', (e) => this.setTheme(e.matches)); } setTheme(isDark) { try { document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light'); if (this.themeToggle) { this.themeToggle.innerHTML = ``; } localStorage.setItem('theme', isDark ? 'dark' : 'light'); console.log(`主题已切换为: ${isDark ? '深色' : '浅色'}`); } catch (error) { console.error('设置主题时出错:', error); } } /** * 显示一个Toast消息 * @param {string} message 显示的消息内容 * @param {string} type 消息类型,可以是'success', 'error', 'info', 'warning' * @param {number} displayTime 显示的时间(毫秒),如果为-1则持续显示直到手动关闭 * @returns {HTMLElement} 返回创建的Toast元素,可用于后续移除 */ showToast(message, type = 'success', displayTime) { try { if (!message) { console.warn('尝试显示空消息'); message = ''; } if (!this.toastContainer) { console.error('Toast容器不存在,正在创建新容器'); this.toastContainer = this.createToastContainer(); if (!this.toastContainer) { console.error('无法创建Toast容器,放弃显示消息'); return null; } } // 检查是否已经存在相同内容的提示 try { const existingToasts = this.toastContainer.querySelectorAll('.toast'); for (const existingToast of existingToasts) { try { const spanElement = existingToast.querySelector('span'); if (spanElement && spanElement.textContent === message) { // 已经存在相同的提示,不再创建新的 return existingToast; } } catch (e) { console.warn('检查现有toast时出错:', e); // 继续检查其他toast元素 } } } catch (e) { console.warn('查询现有toast时出错:', e); // 继续创建新的toast } const toast = document.createElement('div'); toast.className = `toast ${type}`; // 根据类型设置图标 let icon = 'check-circle'; if (type === 'error') icon = 'exclamation-circle'; else if (type === 'warning') icon = 'exclamation-triangle'; else if (type === 'info') icon = 'info-circle'; toast.innerHTML = ` ${message} `; // 如果是持续显示的Toast,添加关闭按钮 if (displayTime === -1) { const closeButton = document.createElement('button'); closeButton.className = 'toast-close'; closeButton.innerHTML = ''; closeButton.addEventListener('click', (e) => { this.hideToast(toast); }); toast.appendChild(closeButton); toast.classList.add('persistent'); } this.toastContainer.appendChild(toast); // 为不同类型的提示设置不同的显示时间 if (displayTime !== -1) { // 如果没有指定时间,则根据消息类型和内容长度设置默认时间 if (displayTime === undefined) { displayTime = message === '截图成功' ? 1500 : type === 'error' ? 5000 : message.length > 50 ? 4000 : 3000; } setTimeout(() => { this.hideToast(toast); }, displayTime); } return toast; } catch (error) { console.error('显示Toast消息时出错:', error); return null; } } /** * 隐藏一个Toast消息 * @param {HTMLElement} toast 要隐藏的Toast元素 */ hideToast(toast) { if (!toast || !toast.parentNode) return; toast.style.opacity = '0'; setTimeout(() => { if (toast.parentNode) { toast.remove(); } }, 300); } closeAllPanels() { if (this.settingsPanel) { this.settingsPanel.classList.remove('active'); } } hideSettingsPanel() { if (this.settingsPanel) { this.settingsPanel.classList.remove('active'); } } toggleSettingsPanel() { if (this.settingsPanel) { this.settingsPanel.classList.toggle('active'); } } closeSettingsPanel() { if (this.settingsPanel) { this.settingsPanel.classList.remove('active'); } } // 检查点击事件,如果点击了设置面板外部,则关闭设置面板 checkClickOutsideSettings(e) { if (this.settingsPanel && !this.settingsPanel.contains(e.target) && !e.target.closest('#settingsToggle')) { this.settingsPanel.classList.remove('active'); } } setupEventListeners() { // 确保所有元素都存在 if (!this.settingsToggle || !this.closeSettings || !this.themeToggle) { console.error('无法设置事件监听器:一些UI元素未找到'); return; } // Settings panel this.settingsToggle.addEventListener('click', () => { this.closeAllPanels(); this.settingsPanel.classList.toggle('active'); }); this.closeSettings.addEventListener('click', () => { this.settingsPanel.classList.remove('active'); }); // Theme toggle this.themeToggle.addEventListener('click', () => { try { const currentTheme = document.documentElement.getAttribute('data-theme'); console.log('当前主题:', currentTheme); this.setTheme(currentTheme !== 'dark'); } catch (error) { console.error('切换主题时出错:', error); } }); // Close panels when clicking outside document.addEventListener('click', (e) => { this.checkClickOutsideSettings(e); }); } } // 创建全局实例 window.UIManager = UIManager; // 确保在DOM加载完毕后才创建UIManager实例 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { window.uiManager = new UIManager(); }); } else { window.uiManager = new UIManager(); } // 导出全局辅助函数 window.showToast = (message, type) => { if (window.uiManager) { return window.uiManager.showToast(message, type); } else { console.error('UI管理器未初始化,无法显示Toast'); return null; } }; window.closeAllPanels = () => { if (window.uiManager) { window.uiManager.closeAllPanels(); } else { console.error('UI管理器未初始化,无法关闭面板'); } };