// 主题切换器 class ThemeSwitcher { constructor() { this.currentTheme = localStorage.getItem('theme') || 'light'; this.init(); } init() { this.applyTheme(this.currentTheme); this.createThemeToggle(); this.setupSystemThemeListener(); } applyTheme(theme) { const root = document.documentElement; if (theme === 'dark') { root.classList.add('dark-theme'); root.classList.remove('light-theme'); } else { root.classList.add('light-theme'); root.classList.remove('dark-theme'); } this.currentTheme = theme; localStorage.setItem('theme', theme); this.updateToggleIcon(); } createThemeToggle() { const toggle = document.createElement('button'); toggle.className = 'theme-toggle'; toggle.innerHTML = this.getThemeIcon(); toggle.setAttribute('aria-label', '切换主题'); toggle.style.cssText = ` position: fixed; top: 1rem; right: 1rem; z-index: 1000; background: rgba(255, 255, 255, 0.9); border: 2px solid var(--border); border-radius: 50%; width: 48px; height: 48px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; box-shadow: var(--shadow-md); transition: all var(--transition-normal); `; toggle.addEventListener('click', () => this.toggleTheme()); document.body.appendChild(toggle); // 悬停效果 toggle.addEventListener('mouseenter', () => { toggle.style.transform = 'scale(1.1)'; toggle.style.boxShadow = 'var(--shadow-lg)'; }); toggle.addEventListener('mouseleave', () => { toggle.style.transform = 'scale(1)'; toggle.style.boxShadow = 'var(--shadow-md)'; }); } getThemeIcon() { return this.currentTheme === 'dark' ? '🌙' : '☀️'; } updateToggleIcon() { const toggle = document.querySelector('.theme-toggle'); if (toggle) { toggle.innerHTML = this.getThemeIcon(); } } toggleTheme() { const newTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; this.applyTheme(newTheme); } setupSystemThemeListener() { const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); mediaQuery.addEventListener('change', (e) => { if (!localStorage.getItem('theme')) { this.applyTheme(e.matches ? 'dark' : 'light'); } }); } } // 初始化主题切换器 document.addEventListener('DOMContentLoaded', () => { new ThemeSwitcher(); }); // 添加页面加载动画 window.addEventListener('load', () => { document.body.classList.add('loaded'); });