/** * 全局应用函数 */ // 核心工具函数 const App = { /** * 初始化应用 */ init() { this.setupEventListeners(); this.setupTheme(); }, /** * 设置事件监听器 */ setupEventListeners() { // 全局事件委托 document.addEventListener('click', (e) => { // 处理移动导航菜单切换 if (e.target.matches('#mobile-menu-toggle') || e.target.closest('#mobile-menu-toggle')) { this.toggleMobileMenu(); } // 处理通知关闭按钮 if (e.target.matches('.close-notification') || e.target.closest('.close-notification')) { const notification = e.target.closest('.notification'); if (notification) this.closeNotification(notification); } // 处理模态框关闭 if (e.target.matches('.modal-overlay')) { const modalId = e.target.dataset.modalId; if (modalId) this.closeModal(modalId); } }); // 响应键盘事件 document.addEventListener('keydown', (e) => { // ESC键关闭模态框 if (e.key === 'Escape') { const modal = document.querySelector('.modal.is-active'); if (modal) { const modalId = modal.id; this.closeModal(modalId); } } }); }, /** * 设置主题相关功能 */ setupTheme() { // 读取用户偏好 const savedTheme = localStorage.getItem('theme'); if (savedTheme) { document.documentElement.setAttribute('data-theme', savedTheme); } // 监听主题切换按钮 document.querySelectorAll('[data-toggle-theme]').forEach(btn => { btn.addEventListener('click', () => { const currentTheme = document.documentElement.getAttribute('data-theme') || 'light'; const newTheme = currentTheme === 'light' ? 'dark' : 'light'; document.documentElement.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); }); }); }, /** * 切换移动菜单 */ toggleMobileMenu() { const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenu) { const isActive = mobileMenu.classList.contains('active'); if (isActive) { mobileMenu.classList.remove('active'); mobileMenu.classList.add('inactive'); } else { mobileMenu.classList.remove('inactive'); mobileMenu.classList.add('active'); } } }, /** * 显示通知 * @param {string} message - 通知消息 * @param {string} type - 通知类型 (success, error, warning, info) * @param {number} duration - 显示时长(ms),0为不自动关闭 */ notify(message, type = 'info', duration = 5000) { // 如果已存在通知容器则使用,否则创建 let container = document.getElementById('notification-container'); if (!container) { container = document.createElement('div'); container.id = 'notification-container'; container.className = 'fixed top-4 right-4 z-50 flex flex-col items-end space-y-2'; document.body.appendChild(container); } // 创建通知元素 const id = 'notification-' + Date.now(); const notification = document.createElement('div'); // 设置通知样式 notification.id = id; notification.className = `notification bg-white shadow-md rounded-md p-4 transform translate-x-full transition-transform duration-300 max-w-sm flex items-start border-l-4 ${this._getNotificationColorClass(type)}`; // 设置通知内容 notification.innerHTML = `
${message}