【前端】【组件库开发】【原理】【无框架开发】现代网页弹窗开发指南:从基础到优化

效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

现代网页弹窗开发指南:从基础到优化

弹窗(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>&times;</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 属性
  • 确保键盘可导航
  • 提供清晰的操作反馈
  • 避免连续弹窗打断用户流程

五、常见问题解决方案

  1. 滚动穿透问题:除了设置overflow: hidden,还需处理触摸设备的touchmove事件。
  2. 弹窗堆叠管理:维护一个弹窗栈,确保正确的显示层级和关闭顺序。
  3. 性能优化:避免频繁创建和销毁弹窗,可采用隐藏/显示模式复用弹窗。
  4. 移动端适配:优化小屏幕上的布局,确保按钮足够大以支持触摸操作。

通过合理的实现和优化,弹窗可以成为提升用户体验的有效工具,而非干扰因素。记住,好的弹窗应该是必要的、简洁的和用户友好的。

源码

<!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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90621.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统】线程

JavaEE—线程 一、进程与线程 1.包含管理 2.资源布局 2.1公共资源 2.2私有资源 二、并发编程 1.多线程优势 1.1创建 1.1.1多线程 1.1.2多进程 1.2通信 1.2.1多线程 1.2.2多进程 1.3调度 1.3.1多线程 1.3.2多进程 1.4销毁 1.4.1多线程 1.4.2多进程 2.多进程…

React 自定义Hook——页面或元素滚动到底部监听 Hook

功能简介 useReachBottom 是一个 React 自定义 Hook&#xff0c;支持监听页面&#xff08;body&#xff09;或任意可滚动元素&#xff08;如 div&#xff09;是否滚动到底部。它能帮助你在用户滑动到底部时触发加载更多、显示提示等操作&#xff0c;极大提升前端交互体验。 亮…

当Powerbi遇到quickbi,性能优化方式对比

powerbi性能优化对于powerbi&#xff0c;性能优化可以从15个方面考虑&#xff1a; 1.过滤源数据【quickbi数据集过滤或sql过滤】2.删除无关列 【quickbi不选字段或sql不查询】3.聚合分析粒度 【quickbi使用sql聚合或计算字段聚合】4.整理字段 【quickbi使用sql聚合或计算字段聚…

ValueConverter转换器WPF

属性搭桥 比如BoolToVisibility 创建两个属性 Bool Visibility 这样不好 混乱了viewmodels 降低了泛用性系统自带的convertor <Window.Resources><BooleanToVisibilityConverter x:Key"booltovis"></BooleanToVisibilityConverter><…

Qt数据库编程详解:SQLite实战指南

Qt数据库编程详解&#xff1a;SQLite实战指南 目录 SQLite数据库简介Qt数据库核心类数据库操作全流程CRUD操作实战运行效果展示 1. SQLite数据库简介 SQLite是Qt内置的轻量级嵌入式数据库&#xff1a; #mermaid-svg-OiZ2cgq9n1G69iH5 {font-family:"trebuchet ms",…

FastAPI 与 OpenIddict 的微服务鉴权整合方案

架构概述基于微服务的身份认证架构采用OAuth 2.0/OpenID Connect协议&#xff0c;OpenIddict作为认证服务器&#xff0c;FastAPI作为资源服务器。系统包含三个核心组件&#xff1a;认证服务、API网关和业务微服务。OpenIddict负责颁发令牌&#xff0c;FastAPI通过JWT验证访问权…

计算两个点的欧式距离

目录 一、概述 二、公式 1、二维空间 2、三维空间 3、n 维空间 三、python实现 一、概述 欧式距离&#xff08;Euclidean Distance&#xff09;是一种在欧几里得空间中度量两个点之间距离的常用方法&#xff0c;其公式根据空间维度的不同而不同 二、公式 1、二维空间 对于二…

八股训练--RabbitMQ

一、经典问题 1.为什么要用MQ&#xff1f; MQ的作用主要是3个&#xff0c; 第一个是流量削峰&#xff1a;当某个活动举行时&#xff0c;访问量可能是平时的几百倍&#xff0c;可能一下会把服务器弄崩溃&#xff0c;所以通过MQ的形式&#xff0c;引入中间者&#xff0c;客户端…

Elasticsearch 文档检索系统

学习笔记&#xff1a;Elasticsearch 文档检索系统 1. 技术栈与核心组件 Node.js&#xff1a;后端运行环境&#xff0c;适合构建高性能 Web 服务。Express&#xff1a;Node.js 的 Web 框架&#xff0c;简化 API 开发。Elasticsearch&#xff1a;分布式全文检索引擎&#xff0c;支…

如何准确查看服务器网络的利用率?

在服务器运维与性能调优过程中&#xff0c;网络利用率是一个不容忽视的关键指标。它反映了服务器带宽资源的实际使用情况&#xff0c;是判断系统瓶颈、规划资源扩展、排查连接问题的重要依据。很多人误以为网络是否正常只要“能上网”或“Ping得通”就可以了&#xff0c;实际上…

掌握Spring声明式事务传播机制:AOP与ThreadLocal的协同工作

声明式事务的传播机制是解决多个事务方法嵌套调用时&#xff0c;事务如何创建、复用、挂起或隔离的核心逻辑。它的实现依赖于事务管理器、事务状态管理、线程上下文绑定等组件的协同&#xff0c;本质是通过一套 “规则判断 状态维护” 的逻辑&#xff0c;在方法调用时动态决定…

@Transactional事务注解的批量回滚机制

关键机制说明&#xff1a;1.​​事务注解生效​​&#xff1a;Transactional(rollbackFor Exception.class)Override Transactional(rollbackFor Exception.class) public Boolean saveUser(UserDTO userDto) {SysUser sysUser new SysUser();BeanUtils.copyProperties(user…

飞算 JavaAI 深度体验:开启 Java 开发智能化新纪元

个人主页&#xff1a;♡喜欢做梦 欢迎 &#x1f44d;点赞 ➕关注 ❤️收藏 &#x1f4ac;评论 目录 一、引言 二、飞算 JavaAI 初印象与功能概览 &#xff08;一&#xff09;初识飞算 JavaAI &#xff08;二&#xff09;核心功能模块概览 三、智能代码生成功能深度体…

pandas销售数据分析

pandas销售数据分析 数据保存在data目录 消费者数据&#xff1a;customers.csv商品数据&#xff1a;products.csv交易数据&#xff1a;transactions.csv customers.csv数据结构&#xff1a;字段描述customer_id客户IDgender性别age年龄region地区membership_date会员日期produc…

访问Windows服务器备份SQL SERVER数据库

以前没有直接访问过Windows服务器,今天刚一看到的是时候有点懵,竟然下意识的使用SecureCRT远程工具去连了一下,然后领导说,看一下用户名,突然意识到,跟我们平时远程桌面是一样的。 一、 win + R 打开命令窗口 二、 输入 mstsc 三、 输入远程地址 四、点击连接,如果有弹…

C++ 面向对象 - 对象定义方法汇总

C对象定义方法汇总 1. 栈上定义方式 1.1 调用无参构造函数的定义方式 无参构造函数有两种&#xff1a; 默认无参构造函数Demo(){}默认值列表构造函数。Demo():a{1},b{2}{} // 使用初始化列表实现对象定义方式&#xff1a; Demo d; Demo d1{}; // 以下定义方式还调用了拷贝构造…

指尖上的魔法:优雅高效的Linux命令手册

一、Linux基础指令 1. ls ls&#xff1a;对于目录&#xff0c;列出该目录下的所有子目录与文件&#xff0c;对于文件&#xff0c;将列出文件名以及其他信息。 -a&#xff1a;列出目录下的所有文件&#xff0c;包含以.开头的隐藏文件 -l:列出文件的详细信息 -d&#xff1a;将目录…

《磁力下载工具实测:资源搜索+高速下载一站式解决方案》

嘿&#xff0c;朋友们&#xff01;我是阿灿&#xff0c;今天给大家带来一个超实用的看片神器&#xff0c;特别适合老司机们使用&#xff0c;保证让你眼前一亮&#xff01;推荐一款比某雷更好用的下载工具&#xff0c;搭配资源搜索神器&#xff0c;轻松获取资源不限速。超强磁力…

Go网络编程基础:网络模型与协议栈概述 - 从理论到实践的完整指南

1. 引言 在当今的互联网时代&#xff0c;网络编程已经成为后端开发的核心技能。Go语言以其出色的并发性能和简洁的语法&#xff0c;在网络编程领域展现出了强大的优势。从Docker、Kubernetes到众多微服务框架&#xff0c;Go已经成为构建高性能网络应用的首选语言之一。 你是否…

Web攻防-SSTI服务端模版注入利用分类语言引擎数据渲染项目工具挖掘思路

知识点&#xff1a; 1、WEB攻防-SSTI-利用分类&功能点 2、WEB攻防-SSTI-利用项目&挖掘思路 SSTI(Server Side Template Injection) 服务器模板注入, 服务端接收了用户的输入&#xff0c;将其作为 Web 应用模板内容的一部分&#xff0c;在进行目标编译渲染的过程中&…