// 现代化UI组件库 const UI = { // 初始化所有自定义下拉框 initSelects() { document.querySelectorAll('select.ui-input, select.ui-select').forEach(select => { if (select.dataset.uiInit) return; // 已初始化 this.createCustomSelect(select); }); }, // 创建自定义下拉框 createCustomSelect(select) { select.dataset.uiInit = 'true'; // 创建包装器 const wrapper = document.createElement('div'); wrapper.className = 'ui-select-wrapper'; select.parentNode.insertBefore(wrapper, select); // 隐藏原生 select select.classList.add('ui-select-native'); wrapper.appendChild(select); // 创建触发器 const trigger = document.createElement('div'); trigger.className = 'ui-select-trigger'; trigger.tabIndex = 0; wrapper.appendChild(trigger); // 创建下拉菜单 const dropdown = document.createElement('div'); dropdown.className = 'ui-select-dropdown'; wrapper.appendChild(dropdown); // 更新选项 const updateOptions = () => { dropdown.innerHTML = ''; const selectedValue = select.value; let selectedText = ''; Array.from(select.options).forEach(option => { const optionEl = document.createElement('div'); optionEl.className = 'ui-select-option'; optionEl.dataset.value = option.value; optionEl.textContent = option.textContent; if (option.value === selectedValue) { optionEl.classList.add('selected'); selectedText = option.textContent; } optionEl.addEventListener('click', () => { select.value = option.value; select.dispatchEvent(new Event('change', { bubbles: true })); wrapper.classList.remove('open'); updateTrigger(); }); dropdown.appendChild(optionEl); }); return selectedText; }; // 更新触发器显示 const updateTrigger = () => { const selectedText = updateOptions(); if (selectedText) { trigger.innerHTML = `${selectedText}`; } else { trigger.innerHTML = `${select.options[0]?.textContent || '请选择'}`; } }; // 初始化 updateTrigger(); // 点击触发器 trigger.addEventListener('click', (e) => { e.stopPropagation(); // 关闭其他下拉框 document.querySelectorAll('.ui-select-wrapper.open').forEach(w => { if (w !== wrapper) w.classList.remove('open'); }); wrapper.classList.toggle('open'); }); // 键盘支持 trigger.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); wrapper.classList.toggle('open'); } else if (e.key === 'Escape') { wrapper.classList.remove('open'); } }); // 监听原生 select 变化 select.addEventListener('change', updateTrigger); // 监听选项变化(用于动态更新) const observer = new MutationObserver(updateTrigger); observer.observe(select, { childList: true, subtree: true }); }, // 显示通知消息 notify(message, type = 'info', duration = 3000) { const container = document.getElementById('notification-container') || this.createNotificationContainer(); const notification = document.createElement('div'); notification.className = `notification notification-${type}`; notification.innerHTML = `
${this.getIcon(type)} ${message}
`; container.appendChild(notification); setTimeout(() => notification.classList.add('show'), 10); setTimeout(() => { notification.classList.remove('show'); setTimeout(() => notification.remove(), 300); }, duration); }, // 显示确认对话框 confirm(title, message, onConfirm, onCancel) { const modal = document.createElement('div'); modal.className = 'ui-modal'; modal.innerHTML = `

${title}

${message}

`; document.body.appendChild(modal); setTimeout(() => modal.classList.add('show'), 10); modal.querySelector('[data-action="confirm"]').onclick = () => { this.closeModal(modal); if (onConfirm) onConfirm(); }; modal.querySelector('[data-action="cancel"]').onclick = () => { this.closeModal(modal); if (onCancel) onCancel(); }; modal.querySelector('.ui-modal-overlay').onclick = () => { this.closeModal(modal); if (onCancel) onCancel(); }; }, // 显示输入对话框 prompt(title, placeholder, defaultValue, onConfirm, onCancel) { const modal = document.createElement('div'); modal.className = 'ui-modal'; modal.innerHTML = `

${title}

`; document.body.appendChild(modal); setTimeout(() => modal.classList.add('show'), 10); const input = modal.querySelector('.ui-input'); input.focus(); input.select(); const confirm = () => { const value = input.value.trim(); if (value) { this.closeModal(modal); if (onConfirm) onConfirm(value); } }; modal.querySelector('[data-action="confirm"]').onclick = confirm; input.onkeypress = (e) => { if (e.key === 'Enter') confirm(); }; modal.querySelector('[data-action="cancel"]').onclick = () => { this.closeModal(modal); if (onCancel) onCancel(); }; modal.querySelector('.ui-modal-overlay').onclick = () => { this.closeModal(modal); if (onCancel) onCancel(); }; }, // 关闭模态框 closeModal(modal) { modal.classList.remove('show'); setTimeout(() => modal.remove(), 300); }, // 创建通知容器 createNotificationContainer() { const container = document.createElement('div'); container.id = 'notification-container'; document.body.appendChild(container); return container; }, // 获取图标 getIcon(type) { const icons = { success: '✓', error: '✕', warning: '⚠', info: 'ℹ' }; return icons[type] || icons.info; } }; // 点击外部关闭下拉框 document.addEventListener('click', (e) => { if (!e.target.closest('.ui-select-wrapper')) { document.querySelectorAll('.ui-select-wrapper.open').forEach(w => { w.classList.remove('open'); }); } }); // 页面加载完成后自动初始化下拉框 document.addEventListener('DOMContentLoaded', () => { UI.initSelects(); }); // 提供手动刷新方法(用于动态加载的内容) UI.refreshSelects = UI.initSelects;