要货了源码集市 · 免费资源
==========================

名称：用AI写的弹窗公告代码
编号：#20360
分类：免费资源
技术栈：Java

说明
----
以下是这份公告弹窗代码的完整功能介绍，涵盖设计特点、核心功能和交互逻辑：### **一、视觉设计与动画效果**1. **现代玻璃态UI** - 采用半透明背景（`rgba(255, 255, 255, 0.9)`）搭配毛玻璃效果（`backdrop-filter: blur(12px)`），与页面背景自然融合 - 圆角设计（24px）+ 柔和阴影（`0 20px 50px rgba(0, 0, 0, 0.12)`），增强立体感 - 顶部渐变装饰条（`#4361ee` 到 `#3a0ca3`），提升视觉焦点2. **分层入场动画** - 弹窗内元素按顺序依次出现（图标→标题→内容→倒计时→按钮→底部信息），每个元素延迟不同时间，形成流畅的层次感 - 动画类型包括：缩放弹出（`popIn`）、淡入上移（`fadeInUp`）、简单淡入（`fadeIn`），增强页面活力3. **微交互效果** - 倒计时数字变化时触发脉冲动画（轻微放大后恢复），直观提示时间流逝 - 按钮悬停时显示流光效果（透明光带从左到右滑动），提升交互反馈 - 关闭按钮悬停时旋转+缩放，增强操作感知### **二、核心功能与逻辑**1. **智能倒计时系统** - **双阶段倒计时**：活动开始前显示“距离开始时间”，开始后自动切换为“距离结束时间”（活动时间固定为10月16日-10月26日） - **动态更新**：每秒刷新倒计时数字（天/时/分/秒），并自动补零保持格式统一（如“03天”而非“3天”） - **结束处理**：活动结束后自动显示“活动已结束”提示，并禁用“参加活动”按钮2. **显示频率控制** - 关闭弹窗后，通过`localStorage`记录关闭时间，**3小时内不再重复显示**，平衡曝光率与用户体验 - 3小时后自动失效，重新打开页面会再次显示，确保用户不会错过活动关键信息3. **多场景适配** - **响应式设计**：在手机、平板、电脑上自动调整布局（如移动端按钮纵向排列） - **内容自适应**：根据活动阶段（未开始/进行中/已结束）自动切换公告文案，保持信息准确性### **三、交互与操作设计**1. **多种关闭方式** - 点击右上角关闭按钮（×） - 点击“我知道了”按钮 - 点击弹窗外部背景区域 - 按下键盘ESC键 所有关闭方式均会触发淡出动画，提升操作流畅度2. **活动跳转功能** - “参加活动”按钮默认链接到指定地址（`https://www.xkwo.com`），点击后在新窗口打开 - 活动未开始时按钮置灰不可点击，开始后自动激活，引导用户参与### **四、技术特点**1. **纯前端实现**：无需后端支持，通过HTML+CSS+JavaScript完成所有功能，可直接嵌入任何网站 2. **无依赖**：不依赖jQuery等框架，代码轻量且独立，避免与现有网站代码冲突 3. **性能优化**： - 关闭弹窗时自动清除倒计时定时器，避免内存泄漏 - 动画仅在必要时触发（如数字变化时才显示脉冲效果） - 通过`localStorage`实现状态记录，无需频繁操作DOM### **总结**这份代码是一个功能完整、体验优良的活动公告弹窗，既具备视觉吸引力（玻璃态设计+流畅动画），又通过智能倒计时和频率控制实现了高效的信息传递，同时兼顾了多设备适配和操作便捷性，适合各类网站的活动推广场景。 &lt;script&gt; // 动态公告弹窗生成函数 function createAnnouncementPopup() { // 检查是否在三小时内已关闭过弹窗 const lastClosedTime = localStorage.getItem('popupLastClosed'); const now = new Date().getTime(); const threeHours = 3 * 60 * 60 * 1000; // 三小时的毫秒数 // 如果三小时内关闭过，则不显示 if (lastClosedTime &amp;&amp; (now - parseInt(lastClosedTime) &lt; threeHours)) { return; } // 创建样式 const style = document.createElement('style'); style.textContent = ` .announcement-popup { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.25); backdrop-filter: blur(8px); display: flex; align-items: center; justify-content: center; z-index: 9999; opacity: 0; visibility: hidden; transition: opacity 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), visibility 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); padding: 1rem; } .announcement-popup.active { opacity: 1; visibility: visible; } .popup-content { background: rgba(255, 255, 255, 0.9); border-radius: 24px; width: 100%; max-width: 550px; padding: 2.5rem 2rem; position: relative; transform: translateY(40px) scale(0.95); opacity: 0; transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); box-shadow: 0 20px 50px rgba(0, 0, 0, 0.12); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.7); overflow: hidden; } .announcement-popup.active .popup-content { transform: translateY(0) scale(1); opacity: 1; } .popup-content::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 8px; background: linear-gradient(90deg, #4361ee, #3a0ca3); } .popup-close { position: absolute; top: 1.5rem; right: 1.5rem; background: rgba(255, 255, 255, 0.7); border: none; font-size: 1.2rem; cursor: pointer; color: #4a4a4a; transition: all 0.3s ease; width: 38px; height: 38px; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); z-index: 10; transform: translate(10px, -10px) scale(0); animation: popIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.5s forwards; } .popup-close:hover { color: #2d2d2d; background: white; transform: rotate(90deg) scale(1.1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); } .popup-icon { width: 80px; height: 80px; background: linear-gradient(135deg, #e0e7ff, #c7d2fe); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 2rem; box-shadow: 0 6px 16px rgba(67, 97, 238, 0.15); position: relative; overflow: hidden; transform: scale(0); animation: popIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s forwards; } .popup-icon::after { content: ''; position: absolute; top: -15px; right: -15px; width: 40px; height: 40px; background: rgba(255, 255, 255, 0.3); border-radius: 50%; } .popup-icon svg { width: 38px; height: 38px; color: #4361ee; position: relative; z-index: 1; transform: scale(0.8); animation: scaleIn 0.4s ease 0.4s forwards; } .popup-title { font-size: 1.8rem; font-weight: 700; color: #1e293b; text-align: center; margin-bottom: 1.5rem; line-height: 1.3; text-shadow: 0 1px 2px rgba(255, 255, 255, 0.6); letter-spacing: -0.02em; opacity: 0; transform: translateY(20px); animation: fadeInUp 0.5s ease 0.6s forwards; } .popup-message { color: #334155; text-align: center; line-height: 1.8; margin-bottom: 1.8rem; font-size: 1.1rem; padding: 0 1rem; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8); opacity: 0; transform: translateY(20px); animation: fadeInUp 0.5s ease 0.7s forwards; } /* 倒计时样式 */ .countdown-container { text-align: center; margin-bottom: 2.2rem; padding: 0 0.5rem; opacity: 0; animation: fadeIn 0.6s ease 0.8s forwards; } .countdown-title { font-size: 1.05rem; color: #d946ef; font-weight: 600; margin-bottom: 1rem; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.6); letter-spacing: 0.03em; } .countdown-timer { display: flex; justify-content: center; gap: 1rem; } .countdown-item { background: rgba(255, 255, 255, 0.9); padding: 1rem 0.8rem; border-radius: 12px; min-width: 68px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.07); border: 1px solid rgba(255, 255, 255, 0.8); position: relative; overflow: hidden; transform: scale(0.9); opacity: 0; } .countdown-item:nth-child(1) { animation: popIn 0.4s ease 0.9s forwards; } .countdown-item:nth-child(2) { animation: popIn 0.4s ease 1.0s forwards; } .countdown-item:nth-child(3) { animation: popIn 0.4s ease 1.1s forwards; } .countdown-item:nth-child(4) { animation: popIn 0.4s ease 1.2s forwards; } .countdown-item::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, #4361ee, #d946ef); opacity: 0; transition: opacity 0.3s ease; } .countdown-item:hover::before { opacity: 1; } .countdown-number { font-size: 1.6rem; font-weight: 700; color: #1e293b; line-height: 1; text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7); font-variant-numeric: tabular-nums; transition: transform 0.3s ease; } .countdown-number.changed { animation: pulse 0.3s ease; } .countdown-label { font-size: 0.8rem; color: #475569; margin-top: 0.5rem; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8); text-transform: uppercase; letter-spacing: 0.05em; } .popup-buttons { display: flex; gap: 1.2rem; margin-bottom: 1.2rem; padding: 0 0.5rem; opacity: 0; animation: fadeIn 0.6s ease 1.3s forwards; } .popup-cta, .popup-action { flex: 1; border: none; padding: 1.1rem 1rem; border-radius: 14px; font-size: 1.05rem; font-weight: 600; cursor: pointer; transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); text-align: center; white-space: nowrap; opacity: 0.95; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); position: relative; overflow: hidden; transform: translateY(20px); opacity: 0; } .popup-cta { background: linear-gradient(135deg, #4361ee, #3a0ca3); color: white; box-shadow: 0 6px 18px rgba(67, 97, 238, 0.25); animation: fadeInUp 0.5s ease 1.4s forwards; } .popup-action { background: linear-gradient(135deg, #f72585, #d946ef); color: white; box-shadow: 0 6px 18px rgba(217, 70, 239, 0.25); text-decoration: none; display: flex; align-items: center; justify-content: center; animation: fadeInUp 0.5s ease 1.5s forwards; } .popup-cta::after, .popup-action::after { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: all 0.6s ease; } .popup-cta:hover::after, .popup-action:hover::after { left: 100%; } .popup-cta:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(67, 97, 238, 0.35); opacity: 1; } .popup-action:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(217, 70, 239, 0.35); opacity: 1; } .popup-cta:active, .popup-action:active { transform: translateY(-2px); } .popup-footer { text-align: center; margin-top: 1.5rem; font-size: 0.9rem; color: #58667e; line-height: 1.6; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8); padding: 0 1rem; opacity: 0; animation: fadeIn 0.6s ease 1.6s forwards; } /* 动画关键帧定义 */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes popIn { 0% { opacity: 0; transform: scale(0.8); } 70% { transform: scale(1.05); } 100% { opacity: 1; transform: scale(1); } } @keyframes scaleIn { from { transform: scale(0.8); } to { transform: scale(1); } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.15); } 100% { transform: scale(1); } } @media (max-width: 480px) { .popup-content { padding: 2rem 1.5rem; border-radius: 20px; } .popup-buttons { flex-direction: column; gap: 1rem; } .popup-title { font-size: 1.6rem; margin-bottom: 1.2rem; } .popup-message { font-size: 1rem; margin-bottom: 1.5rem; } .countdown-container { margin-bottom: 1.8rem; } .countdown-item { min-width: 60px; padding: 0.8rem 0.6rem; } .countdown-number { font-size: 1.4rem; } .popup-cta, .popup-action { padding: 1.05rem; font-size: 1rem; } .popup-icon { width: 70px; height: 70px; margin-bottom: 1.8rem; } } `; document.head.appendChild(style); // 创建弹窗HTML const popup = document.createElement('div'); popup.className = 'announcement-popup'; popup.innerHTML = ` &lt;div class=&quot;popup-content&quot;&gt; &lt;button class=&quot;popup-close&quot;&gt;&lt;/button&gt; &lt;div class=&quot;popup-icon&quot;&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; fill=&quot;none&quot; viewBox=&quot;0 0 24 24&quot; stroke=&quot;currentColor&quot;&gt; &lt;path stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z&quot; /&gt; &lt;/svg&gt; &lt;/div&gt; &lt;h3 class=&quot;popup-title&quot;&gt;限时活动公告&lt;/h3&gt; &lt;p class=&quot;popup-message&quot; id=&quot;popupMessage&quot;&gt; 年度回馈活动即将开始！设置提醒，第一时间参与活动，抢占丰厚奖励！ &lt;/p&gt; &lt;!-- 倒计时区域 --&gt; &lt;div class=&quot;countdown-container&quot;&gt; &lt;div class=&quot;countdown-title&quot; id=&quot;countdownTitle&quot;&gt;活动开始倒计时&lt;/div&gt; &lt;div class=&quot;countdown-timer&quot;&gt; &lt;div class=&quot;countdown-item&quot;&gt; &lt;div class=&quot;countdown-number&quot; id=&quot;days&quot;&gt;00&lt;/div&gt; &lt;div class=&quot;countdown-label&quot;&gt;天&lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;countdown-item&quot;&gt; &lt;div class=&quot;countdown-number&quot; id=&quot;hours&quot;&gt;00&lt;/div&gt; &lt;div class=&quot;countdown-label&quot;&gt;时&lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;countdown-item&quot;&gt; &lt;div class=&quot;countdown-number&quot; id=&quot;minutes&quot;&gt;00&lt;/div&gt; &lt;div class=&quot;countdown-label&quot;&gt;分&lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;countdown-item&quot;&gt; &lt;div class=&quot;countdown-number&quot; id=&quot;seconds&quot;&gt;00&lt;/div&gt; &lt;div class=&quot;countdown-label&quot;&gt;秒&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;popup-buttons&quot;&gt; &lt;button class=&quot;popup-cta&quot;&gt;我知道了&lt;/button&gt; &lt;a href=&quot;https://www.xkwo.com/&quot; target=&quot;_blank&quot; class=&quot;popup-action&quot; id=&quot;actionButton&quot; style=&quot;opacity:0.7;pointer-events:none;&quot;&gt; 活动未开始 &lt;/a&gt; &lt;/div&gt; &lt;div class=&quot;popup-footer&quot;&gt;活动时间：10月16日-10月26日 | 如有疑问，请联系在线客服&lt;/div&gt; &lt;/div&gt; `; document.body.appendChild(popup); // 显示弹窗（延迟1秒，让页面加载完成） setTimeout(() =&gt; { popup.classList.add('active'); }, 1000); // 关闭弹窗的核心函数 - 记录关闭时间 function closePopup() { // 记录当前关闭时间到localStorage localStorage.setItem('popupLastClosed', now.toString()); popup.classList.remove('active'); // 清除倒计时定时器 if (window.countdownTimer) { clearInterval(window.countdownTimer); window.countdownTimer = null; } // 动画结束后移除弹窗 setTimeout(() =&gt; { if (popup.parentNode) { popup.remove(); } }, 600); } // 倒计时功能实现 - 带数字变化动画 function startSmartCountdown() { // 保存上次倒计时数值，用于检测变化 let lastValues = { days: '00', hours: '00', minutes: '00', seconds: '00' }; // 设置活动时间 const startTime = new Date(); startTime.setMonth(9); startTime.setDate(16); startTime.setHours(0, 0, 0, 0); const endTime = new Date(); endTime.setMonth(9); endTime.setDate(26); endTime.setHours(23, 59, 59, 0); const now = new Date(); let targetTime, isBeforeStart; if (now &lt; startTime) { targetTime = startTime; isBeforeStart = true; } else if (now &lt;= endTime) { targetTime = endTime; isBeforeStart = false; updateForActiveEvent(); } else { document.getElementById('countdownTitle').innerText = '活动已结束'; document.getElementById('countdown-timer').innerHTML = '&lt;div style=&quot;color:#58667e;padding:1rem 0;&quot;&gt;敬请期待下次活动&lt;/div&gt;'; document.getElementById('popupMessage').textContent = '本次年度回馈活动已圆满结束，感谢您的参与！更多精彩活动敬请关注。'; document.getElementById('actionButton').textContent = '活动已结束'; return; } function updateForActiveEvent() { document.getElementById('countdownTitle').innerText = '活动剩余时间'; document.getElementById('popupMessage').textContent = '年度回馈活动火热进行中！参与活动即可获得丰厚奖励，抓紧时间点击参与，错过再等一年！'; document.getElementById('actionButton').textContent = '参加活动'; document.getElementById('actionButton').style.opacity = '0.95'; document.getElementById('actionButton').style.pointerEvents = 'auto'; } function updateCountdown() { const now = new Date().getTime(); const distance = targetTime - now; if (isBeforeStart &amp;&amp; now &gt;= startTime) { targetTime = endTime; isBeforeStart = false; updateForActiveEvent(); } // 计算时间差 const days = Math.floor(distance / (1000 * 60 * 60 * 24)).toString().padStart(2, '0'); const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)).toString().padStart(2, '0'); const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)).toString().padStart(2, '0'); const seconds = Math.floor((distance % (1000 * 60)) / 1000).toString().padStart(2, '0'); // 更新DOM并添加变化动画 const elements = { days: document.getElementById('days'), hours: document.getElementById('hours'), minutes: document.getElementById('minutes'), seconds: document.getElementById('seconds') }; // 检查每个数值是否变化，变化则添加动画 if (days !== lastValues.days) { elements.days.innerText = days; elements.days.classList.add('changed'); setTimeout(() =&gt; elements.days.classList.remove('changed'), 300); lastValues.days = days; } if (hours !== lastValues.hours) { elements.hours.innerText = hours; elements.hours.classList.add('changed'); setTimeout(() =&gt; elements.hours.classList.remove('changed'), 300); lastValues.hours = hours; } if (minutes !== lastValues.minutes) { elements.minutes.innerText = minutes; elements.minutes.classList.add('changed'); setTimeout(() =&gt; elements.minutes.classList.remove('changed'), 300); lastValues.minutes = minutes; } if (seconds !== lastValues.seconds) { elements.seconds.innerText = seconds; elements.seconds.classList.add('changed'); setTimeout(() =&gt; elements.seconds.classList.remove('changed'), 300); lastValues.seconds = seconds; } // 活动结束处理 if (distance &lt; 0 &amp;&amp; !isBeforeStart) { clearInterval(window.countdownTimer); window.countdownTimer = null; document.getElementById('countdownTitle').innerText = '活动已结束'; document.getElementById('countdown-timer').innerHTML = '&lt;div style=&quot;color:#58667e;padding:1rem 0;&quot;&gt;敬请期待下次活动&lt;/div&gt;'; document.getElementById('popupMessage').textContent = '本次年度回馈活动已圆满结束，感谢您的参与！更多精彩活动敬请关注。'; document.getElementById('actionButton').textContent = '活动已结束'; document.getElementById('actionButton').style.opacity = '0.7'; document.getElementById('actionButton').style.pointerEvents = 'none'; } } updateCountdown(); window.countdownTimer = setInterval(updateCountdown, 1000); } // 启动倒计时 startSmartCountdown(); // 绑定关闭事件 const closeBtn = popup.querySelector('.popup-close'); const ctaBtn = popup.querySelector('.popup-cta'); closeBtn.addEventListener('click', () =&gt; closePopup()); ctaBtn.addEventListener('click', () =&gt; closePopup()); popup.addEventListener('click', (e) =&gt; { if (e.target === popup) closePopup(); }); const handleEscKey = (e) =&gt; { if (e.key === 'Escape' &amp;&amp; popup.classList.contains('active')) { closePopup(); document.removeEventListener('keydown', handleEscKey); } }; document.addEventListener('keydown', handleEscKey); } // 页面加载完成后执行 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () =&gt; { setTimeout(createAnnouncementPopup, 500); }); } else { setTimeout(createAnnouncementPopup, 500); } &lt;/script&gt; 复制代码

交付说明
--------
当前商品尚未上传完整工程压缩包，本文件为授权与部署说明。请通过订单号在「订单查询」核对后联系站点补发源码包。

站点：https://www.yaohuole.homes
