// js/notifications.js - 提供Toast和Dialog两种通知 // 这个模块在初始化时需要知道容器的DOM元素 let toastContainer; let dialogContainer; function hideToast(toastElement) { if (!toastElement) return; toastElement.classList.remove('show'); toastElement.addEventListener('transitionend', () => toastElement.remove(), { once: true }); } export const notification = { init: (toastEl, dialogEl) => { toastContainer = toastEl; dialogContainer = dialogEl; }, toast: (message, type = 'info', duration = 3000) => { const icons = { success: 'fa-check-circle', error: 'fa-times-circle', info: 'fa-info-circle', warning: 'fa-exclamation-triangle' }; const iconClass = icons[type] || 'fa-info-circle'; const toastElement = document.createElement('div'); toastElement.className = `toast ${type}`; toastElement.innerHTML = `

${message}

`; toastContainer.appendChild(toastElement); requestAnimationFrame(() => toastElement.classList.add('show')); const timeoutId = setTimeout(() => hideToast(toastElement), duration); toastElement.querySelector('[data-toast-close]').addEventListener('click', () => { clearTimeout(timeoutId); hideToast(toastElement); }); }, confirm: (message) => { return new Promise(resolve => { const dialogHTML = `

${message}

`; dialogContainer.innerHTML = dialogHTML; dialogContainer.classList.add('active'); const eventHandler = (e) => { const actionButton = e.target.closest('[data-action]'); if (!actionButton) return; closeDialog(actionButton.dataset.action === 'confirm'); }; const closeDialog = (result) => { dialogContainer.removeEventListener('click', eventHandler); dialogContainer.classList.remove('active'); setTimeout(() => { dialogContainer.innerHTML = ''; resolve(result); }, 200); }; dialogContainer.addEventListener('click', eventHandler); }); } };