效果
现代网页弹窗开发指南:从基础到优化
弹窗(Modal)作为网页交互的重要组件,在用户通知、确认操作和表单输入等场景中广泛应用。本文将循序渐进地讲解弹窗的技术实现与最佳实践。
一、弹窗基础概念
弹窗是一种覆盖在主内容之上的浮动容器,具有以下核心特征:
- 模态性:阻止用户与背景内容交互
- 聚焦性:强制用户关注弹窗内容
- 临时性:完成操作后可关闭并消失
- 层级性:位于页面其他元素之上
常见应用场景包括:确认对话框、表单提交、通知提示、图片预览和登录注册等。
二、基础弹窗实现
HTML 结构
<!-- 弹窗容器 -->
<div class="modal" id="basic-modal"><!-- 遮罩层 --><div class="modal-overlay" data-close></div><!-- 弹窗内容 --><div class="modal-container"><div class="modal-header"><h2>弹窗标题</h2><button class="modal-close" data-close>×</button></div><div class="modal-body"><p>弹窗内容区域</p></div><div class="modal-footer"><button class="modal-btn" data-close>关闭</button></div></div>
</div>
CSS 核心样式
/* 基础样式 */
.modal {position: fixed;inset: 0;z-index: 1000;display: none;
}/* 遮罩层 */
.modal-overlay {position: absolute;inset: 0;background: rgba(0, 0, 0, 0.5);
}/* 弹窗容器 */
.modal-container {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);background: white;border-radius: 8px;min-width: 300px;max-width: 90%;
}
JavaScript 控制逻辑
// 打开弹窗
function openModal(modalId) {const modal = document.getElementById(modalId);modal.style.display = 'block';document.body.style.overflow = 'hidden'; // 禁止背景滚动
}// 关闭弹窗
function closeModal(modalId) {const modal = document.getElementById(modalId);modal.style.display = 'none';document.body.style.overflow = ''; // 恢复背景滚动
}// 事件绑定
document.querySelectorAll('[data-open]').forEach(btn => {btn.addEventListener('click', () => {openModal(btn.dataset.open);});
});document.querySelectorAll('[data-close]').forEach(el => {el.addEventListener('click', () => {const modal = el.closest('.modal');closeModal(modal.id);});
});
三、进阶功能实现
1. 动画效果
添加平滑过渡动画增强用户体验:
/* 动画效果 */
.modal-container {opacity: 0;transform: translate(-50%, -60%) scale(0.98);transition: all 0.3s ease;
}.modal.active .modal-container {opacity: 1;transform: translate(-50%, -50%) scale(1);
}.modal-overlay {opacity: 0;transition: opacity 0.3s ease;
}.modal.active .modal-overlay {opacity: 1;
}
2. 键盘操作支持
// 监听ESC键关闭弹窗
document.addEventListener('keydown', (e) => {if (e.key === 'Escape') {document.querySelectorAll('.modal.active').forEach(modal => {closeModal(modal.id);});}
});
3. 响应式设计
/* 响应式调整 */
@media (max-width: 768px) {.modal-container {width: 95%;max-height: 90vh;overflow-y: auto;}
}
四、设计最佳实践
视觉设计
- 使用阴影和层级区分弹窗与背景
- 保持一致的边框圆角和间距
- 为不同类型弹窗使用语义化色彩(成功、警告、错误)
交互体验
- 添加打开/关闭动画,避免突兀切换
- 确保关闭按钮明显可见
- 支持点击遮罩层和 ESC 键关闭
- 弹窗打开时自动聚焦到主要操作按钮
可访问性优化
- 添加适当的 ARIA 属性
- 确保键盘可导航
- 提供清晰的操作反馈
- 避免连续弹窗打断用户流程
五、常见问题解决方案
- 滚动穿透问题:除了设置
overflow: hidden
,还需处理触摸设备的touchmove
事件。 - 弹窗堆叠管理:维护一个弹窗栈,确保正确的显示层级和关闭顺序。
- 性能优化:避免频繁创建和销毁弹窗,可采用隐藏/显示模式复用弹窗。
- 移动端适配:优化小屏幕上的布局,确保按钮足够大以支持触摸操作。
通过合理的实现和优化,弹窗可以成为提升用户体验的有效工具,而非干扰因素。记住,好的弹窗应该是必要的、简洁的和用户友好的。
源码
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>自定义弹窗组件示例</title><script src="https://cdn.tailwindcss.com"></script><link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"><script>tailwind.config = {theme: {extend: {colors: {primary: '#165DFF',secondary: '#6B7280',success: '#36D399',warning: '#FFAB00',danger: '#F43F5E',},fontFamily: {inter: ['Inter', 'sans-serif'],},},}}</script><style type="text/tailwindcss">@layer utilities {.content-auto {content-visibility: auto;}.modal-backdrop {backdrop-filter: blur(4px);}.modal-transition {transition: opacity 0.3s ease, transform 0.3s ease;}.btn-shadow {box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);}.modal-container-center {@apply fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2;}}</style>
</head>
<body class="font-inter bg-gray-50 min-h-screen flex flex-col"><!-- 导航栏 --><nav class="bg-white shadow-sm sticky top-0 z-50"><div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"><div class="flex justify-between h-16"><div class="flex items-center"><span class="text-primary font-bold text-xl">ModalDemo</span></div><div class="flex items-center space-x-4"><button class="px-3 py-2 rounded-md text-sm font-medium text-gray-600 hover:text-primary transition-colors duration-200"><i class="fa fa-github mr-1"></i> 源码</button><button class="px-3 py-2 rounded-md text-sm font-medium text-white bg-primary hover:bg-primary/90 transition-colors duration-200 btn-shadow"><i class="fa fa-download mr-1"></i> 下载</button></div></div></div></nav><!-- 主内容区 --><main class="flex-grow flex flex-col items-center justify-center p-4 sm:p-6 lg:p-8"><div class="max-w-4xl w-full bg-white rounded-xl shadow-md p-6 sm:p-8 mb-8"><h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-gray-800 mb-4">自定义弹窗组件示例</h1><p class="text-gray-600 mb-8">探索使用纯 JavaScript 实现的各种弹窗样式和交互效果。点击下方按钮查看不同类型的模态框。</p><div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 sm:gap-6"><button class="modal-trigger w-full px-4 py-3 bg-primary text-white rounded-lg hover:bg-primary/90 transition-all duration-200 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center" data-target="modal-basic"><i class="fa fa-window-maximize mr-2"></i> 基础弹窗</button><button class="modal-trigger w-full px-4 py-3 bg-secondary text-white rounded-lg hover:bg-secondary/90 transition-all duration-200 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center" data-target="modal-info"><i class="fa fa-info-circle mr-2"></i> 信息弹窗</button><button class="modal-trigger w-full px-4 py-3 bg-success text-white rounded-lg hover:bg-success/90 transition-all duration-200 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center" data-target="modal-success"><i class="fa fa-check-circle mr-2"></i> 成功弹窗</button><button class="modal-trigger w-full px-4 py-3 bg-warning text-white rounded-lg hover:bg-warning/90 transition-all duration-200 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center" data-target="modal-warning"><i class="fa fa-exclamation-triangle mr-2"></i> 警告弹窗</button><button class="modal-trigger w-full px-4 py-3 bg-danger text-white rounded-lg hover:bg-danger/90 transition-all duration-200 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center" data-target="modal-danger"><i class="fa fa-times-circle mr-2"></i> 错误弹窗</button><button class="modal-trigger w-full px-4 py-3 bg-gray-700 text-white rounded-lg hover:bg-gray-800 transition-all duration-200 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center" data-target="modal-confirm"><i class="fa fa-question-circle mr-2"></i> 确认弹窗</button></div></div><div class="max-w-4xl w-full bg-white rounded-xl shadow-md p-6 sm:p-8"><h2 class="text-2xl font-bold text-gray-800 mb-4">表单弹窗示例</h2><p class="text-gray-600 mb-6">自定义弹窗组件也可以轻松集成表单功能。</p><button class="modal-trigger px-5 py-3 bg-primary text-white rounded-lg hover:bg-primary/90 transition-all duration-200 transform hover:-translate-y-1 hover:shadow-lg flex items-center justify-center" data-target="modal-form"><i class="fa fa-user-plus mr-2"></i> 打开表单弹窗</button></div></main><!-- 页脚 --><footer class="bg-gray-800 text-white py-8"><div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"><div class="flex flex-col md:flex-row justify-between items-center"><div class="mb-4 md:mb-0"><span class="text-xl font-bold">ModalDemo</span><p class="text-gray-400 mt-1">使用纯 JavaScript 创建的精美弹窗</p></div><div class="flex space-x-4"><a href="#" class="text-gray-400 hover:text-white transition-colors duration-200"><i class="fa fa-github text-xl"></i></a><a href="#" class="text-gray-400 hover:text-white transition-colors duration-200"><i class="fa fa-twitter text-xl"></i></a><a href="#" class="text-gray-400 hover:text-white transition-colors duration-200"><i class="fa fa-linkedin text-xl"></i></a></div></div><div class="border-t border-gray-700 mt-6 pt-6 text-center text-gray-400 text-sm">© 2025 ModalDemo. 保留所有权利。</div></div></footer><!-- 基础弹窗 --><div class="modal fixed inset-0 z-50 hidden" id="modal-basic"><div class="absolute inset-0 bg-black/50 modal-backdrop" data-close="true"></div><div class="modal-container max-w-md w-full mx-4 bg-white rounded-xl shadow-2xl overflow-hidden modal-container-center transform transition-all duration-300 scale-95 opacity-0" id="modal-basic-container"><div class="modal-header bg-gray-50 px-6 py-4 flex justify-between items-center"><h2 class="text-xl font-bold text-gray-800"><i class="fa fa-window-maximize text-primary mr-2"></i>基础弹窗</h2><button class="text-gray-500 hover:text-gray-700 transition-colors duration-200 close-modal" data-target="modal-basic"><i class="fa fa-times text-xl"></i></button></div><div class="modal-content px-6 py-4 text-gray-700"><p>这是一个基本的弹窗示例,展示了纯 JavaScript 实现的弹窗功能。</p><p class="mt-2">你可以自定义弹窗的内容、样式和交互逻辑。</p></div><div class="modal-footer px-6 py-4 bg-gray-50 flex justify-end space-x-3"><button class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors duration-200 close-modal" data-target="modal-basic">取消</button><button class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors duration-200 close-modal" data-target="modal-basic">确认</button></div></div></div><!-- 信息弹窗 --><div class="modal fixed inset-0 z-50 hidden" id="modal-info"><div class="absolute inset-0 bg-black/50 modal-backdrop" data-close="true"></div><div class="modal-container max-w-md w-full mx-4 bg-white rounded-xl shadow-2xl overflow-hidden modal-container-center transform transition-all duration-300 scale-95 opacity-0" id="modal-info-container"><div class="modal-header bg-blue-50 px-6 py-4 flex justify-between items-center"><h2 class="text-xl font-bold text-blue-800"><i class="fa fa-info-circle text-blue-500 mr-2"></i>信息提示</h2><button class="text-gray-500 hover:text-gray-700 transition-colors duration-200 close-modal" data-target="modal-info"><i class="fa fa-times text-xl"></i></button></div><div class="modal-content px-6 py-4 text-gray-700"><div class="flex items-start"><div class="flex-shrink-0 mt-0.5"><i class="fa fa-info-circle text-blue-500 text-3xl"></i></div><div class="ml-4"><p class="text-gray-700">这是一个信息提示弹窗,用于向用户展示重要信息。</p><p class="mt-2 text-gray-600">信息弹窗通常用于展示帮助文档、使用指南或系统通知等内容。</p></div></div></div><div class="modal-footer px-6 py-4 bg-blue-50 flex justify-end"><button class="px-4 py-2 bg-blue-100 text-blue-800 rounded-lg hover:bg-blue-200 transition-colors duration-200 close-modal" data-target="modal-info">我知道了</button></div></div></div><!-- 成功弹窗 --><div class="modal fixed inset-0 z-50 hidden" id="modal-success"><div class="absolute inset-0 bg-black/50 modal-backdrop" data-close="true"></div><div class="modal-container max-w-md w-full mx-4 bg-white rounded-xl shadow-2xl overflow-hidden modal-container-center transform transition-all duration-300 scale-95 opacity-0" id="modal-success-container"><div class="modal-header bg-green-50 px-6 py-4 flex justify-between items-center"><h2 class="text-xl font-bold text-green-800"><i class="fa fa-check-circle text-green-500 mr-2"></i>操作成功</h2><button class="text-gray-500 hover:text-gray-700 transition-colors duration-200 close-modal" data-target="modal-success"><i class="fa fa-times text-xl"></i></button></div><div class="modal-content px-6 py-4 text-gray-700"><div class="flex items-start"><div class="flex-shrink-0 mt-0.5"><i class="fa fa-check-circle text-green-500 text-3xl"></i></div><div class="ml-4"><p class="text-gray-700">恭喜!你的操作已成功完成。</p><p class="mt-2 text-gray-600">你可以继续其他操作,或返回上一页。</p></div></div></div><div class="modal-footer px-6 py-4 bg-green-50 flex justify-end"><button class="px-4 py-2 bg-green-100 text-green-800 rounded-lg hover:bg-green-200 transition-colors duration-200 close-modal" data-target="modal-success">完成</button></div></div></div><!-- 警告弹窗 --><div class="modal fixed inset-0 z-50 hidden" id="modal-warning"><div class="absolute inset-0 bg-black/50 modal-backdrop" data-close="true"></div><div class="modal-container max-w-md w-full mx-4 bg-white rounded-xl shadow-2xl overflow-hidden modal-container-center transform transition-all duration-300 scale-95 opacity-0" id="modal-warning-container"><div class="modal-header bg-yellow-50 px-6 py-4 flex justify-between items-center"><h2 class="text-xl font-bold text-yellow-800"><i class="fa fa-exclamation-triangle text-yellow-500 mr-2"></i>警告提示</h2><button class="text-gray-500 hover:text-gray-700 transition-colors duration-200 close-modal" data-target="modal-warning"><i class="fa fa-times text-xl"></i></button></div><div class="modal-content px-6 py-4 text-gray-700"><div class="flex items-start"><div class="flex-shrink-0 mt-0.5"><i class="fa fa-exclamation-triangle text-yellow-500 text-3xl"></i></div><div class="ml-4"><p class="text-gray-700">注意!此操作可能会产生不可预期的结果。</p><p class="mt-2 text-gray-600">请确认你已经了解相关风险,并谨慎操作。</p></div></div></div><div class="modal-footer px-6 py-4 bg-yellow-50 flex justify-end space-x-3"><button class="px-4 py-2 bg-yellow-100 text-yellow-800 rounded-lg hover:bg-yellow-200 transition-colors duration-200 close-modal" data-target="modal-warning">取消</button><button class="px-4 py-2 bg-yellow-600 text-white rounded-lg hover:bg-yellow-700 transition-colors duration-200 close-modal" data-target="modal-warning">继续</button></div></div></div><!-- 错误弹窗 --><div class="modal fixed inset-0 z-50 hidden" id="modal-danger"><div class="absolute inset-0 bg-black/50 modal-backdrop" data-close="true"></div><div class="modal-container max-w-md w-full mx-4 bg-white rounded-xl shadow-2xl overflow-hidden modal-container-center transform transition-all duration-300 scale-95 opacity-0" id="modal-danger-container"><div class="modal-header bg-red-50 px-6 py-4 flex justify-between items-center"><h2 class="text-xl font-bold text-red-800"><i class="fa fa-times-circle text-red-500 mr-2"></i>操作失败</h2><button class="text-gray-500 hover:text-gray-700 transition-colors duration-200 close-modal" data-target="modal-danger"><i class="fa fa-times text-xl"></i></button></div><div class="modal-content px-6 py-4 text-gray-700"><div class="flex items-start"><div class="flex-shrink-0 mt-0.5"><i class="fa fa-times-circle text-red-500 text-3xl"></i></div><div class="ml-4"><p class="text-gray-700">抱歉,你的操作未能成功完成。</p><p class="mt-2 text-gray-600">错误信息:网络连接超时,请检查你的网络设置并重试。</p></div></div></div><div class="modal-footer px-6 py-4 bg-red-50 flex justify-end space-x-3"><button class="px-4 py-2 bg-red-100 text-red-800 rounded-lg hover:bg-red-200 transition-colors duration-200 close-modal" data-target="modal-danger">关闭</button><button class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors duration-200 close-modal" data-target="modal-danger">重试</button></div></div></div><!-- 确认弹窗 --><div class="modal fixed inset-0 z-50 hidden" id="modal-confirm"><div class="absolute inset-0 bg-black/50 modal-backdrop" data-close="true"></div><div class="modal-container max-w-md w-full mx-4 bg-white rounded-xl shadow-2xl overflow-hidden modal-container-center transform transition-all duration-300 scale-95 opacity-0" id="modal-confirm-container"><div class="modal-header bg-gray-50 px-6 py-4 flex justify-between items-center"><h2 class="text-xl font-bold text-gray-800"><i class="fa fa-question-circle text-gray-500 mr-2"></i>确认操作</h2><button class="text-gray-500 hover:text-gray-700 transition-colors duration-200 close-modal" data-target="modal-confirm"><i class="fa fa-times text-xl"></i></button></div><div class="modal-content px-6 py-4 text-gray-700"><div class="flex items-start"><div class="flex-shrink-0 mt-0.5"><i class="fa fa-question-circle text-gray-500 text-3xl"></i></div><div class="ml-4"><p class="text-gray-700">你确定要执行此操作吗?此操作无法撤销。</p><p class="mt-2 text-gray-600">请确认你已经了解相关风险,并谨慎操作。</p></div></div></div><div class="modal-footer px-6 py-4 bg-gray-50 flex justify-end space-x-3"><button class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors duration-200 close-modal" data-target="modal-confirm">取消</button><button class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors duration-200 close-modal" data-target="modal-confirm">确认删除</button></div></div></div><!-- 表单弹窗 --><div class="modal fixed inset-0 z-50 hidden" id="modal-form"><div class="absolute inset-0 bg-black/50 modal-backdrop" data-close="true"></div><div class="modal-container max-w-lg w-full mx-4 bg-white rounded-xl shadow-2xl overflow-hidden modal-container-center transform transition-all duration-300 scale-95 opacity-0" id="modal-form-container"><div class="modal-header bg-primary px-6 py-4 flex justify-between items-center"><h2 class="text-xl font-bold text-white"><i class="fa fa-user-plus mr-2"></i>创建新用户</h2><button class="text-white hover:text-gray-200 transition-colors duration-200 close-modal" data-target="modal-form"><i class="fa fa-times text-xl"></i></button></div><div class="modal-content px-6 py-4 text-gray-700"><form id="user-form" class="space-y-4"><div class="grid grid-cols-1 md:grid-cols-2 gap-4"><div><label for="first-name" class="block text-sm font-medium text-gray-700 mb-1">姓氏</label><input type="text" id="first-name" name="first-name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200" placeholder="请输入姓氏"></div><div><label for="last-name" class="block text-sm font-medium text-gray-700 mb-1">名字</label><input type="text" id="last-name" name="last-name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200" placeholder="请输入名字"></div></div><div><label for="email" class="block text-sm font-medium text-gray-700 mb-1">电子邮箱</label><input type="email" id="email" name="email" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200" placeholder="请输入电子邮箱"></div><div><label for="role" class="block text-sm font-medium text-gray-700 mb-1">用户角色</label><select id="role" name="role" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200"><option value="">请选择用户角色</option><option value="admin">管理员</option><option value="editor">编辑</option><option value="user">普通用户</option></select></div><div><label class="block text-sm font-medium text-gray-700 mb-1">用户权限</label><div class="grid grid-cols-2 gap-2"><label class="flex items-center space-x-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50 transition-colors duration-200"><input type="checkbox" name="permissions[]" value="view"><span>查看权限</span></label><label class="flex items-center space-x-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50 transition-colors duration-200"><input type="checkbox" name="permissions[]" value="edit"><span>编辑权限</span></label><label class="flex items-center space-x-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50 transition-colors duration-200"><input type="checkbox" name="permissions[]" value="delete"><span>删除权限</span></label><label class="flex items-center space-x-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50 transition-colors duration-200"><input type="checkbox" name="permissions[]" value="admin"><span>管理权限</span></label></div></div><div><label for="notes" class="block text-sm font-medium text-gray-700 mb-1">备注信息</label><textarea id="notes" name="notes" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary transition-colors duration-200" placeholder="请输入备注信息(选填)"></textarea></div></form></div><div class="modal-footer px-6 py-4 bg-gray-50 flex justify-end space-x-3"><button class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors duration-200 close-modal" data-target="modal-form">取消</button><button class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors duration-200" id="submit-form">创建用户</button></div></div></div><script>// 打开弹窗函数function openModal(modalId) {const modal = document.getElementById(modalId);const container = document.getElementById(`${modalId}-container`);if (modal && container) {// 显示弹窗modal.classList.remove('hidden');// 添加动画效果 - 延迟 10ms 以确保过渡效果生效setTimeout(() => {container.classList.remove('scale-95', 'opacity-0');container.classList.add('scale-100', 'opacity-100');}, 10);// 阻止背景滚动document.body.style.overflow = 'hidden';}}// 关闭弹窗函数function closeModal(modalId) {const modal = document.getElementById(modalId);const container = document.getElementById(`${modalId}-container`);if (modal && container) {// 添加关闭动画container.classList.remove('scale-100', 'opacity-100');container.classList.add('scale-95', 'opacity-0');// 延迟隐藏弹窗以等待动画完成setTimeout(() => {modal.classList.add('hidden');}, 300);// 恢复背景滚动document.body.style.overflow = '';}}// 绑定打开弹窗事件document.querySelectorAll('.modal-trigger').forEach(button => {button.addEventListener('click', function() {const targetModal = this.getAttribute('data-target');openModal(targetModal);// 添加按钮动画效果this.classList.add('scale-95');setTimeout(() => {this.classList.remove('scale-95');}, 150);});});// 绑定关闭弹窗事件document.querySelectorAll('.close-modal').forEach(button => {button.addEventListener('click', function() {const targetModal = this.getAttribute('data-target');closeModal(targetModal);// 添加按钮动画效果this.classList.add('scale-95');setTimeout(() => {this.classList.remove('scale-95');}, 150);});});// 点击遮罩层关闭弹窗document.querySelectorAll('.modal-backdrop').forEach(backdrop => {backdrop.addEventListener('click', function() {if (this.getAttribute('data-close') === 'true') {const modal = this.closest('.modal');const modalId = modal.id;closeModal(modalId);}});});// 表单提交处理document.getElementById('submit-form').addEventListener('click', function() {const form = document.getElementById('user-form');const formData = new FormData(form);const userData = {};// 收集表单数据formData.forEach((value, key) => {if (userData[key]) {if (!Array.isArray(userData[key])) {userData[key] = [userData[key]];}userData[key].push(value);} else {userData[key] = value;}});// 模拟表单提交console.log('提交用户数据:', userData);// 关闭表单弹窗closeModal('modal-form');// 显示成功消息setTimeout(() => {openModal('modal-success');}, 300);// 重置表单form.reset();});</script>
</body>
</html>