一、使用前提 运行环境:任意支持 HTML/CSS/JavaScript 的网页环境(静态 HTML、PHP、Python Web、Vue/React 等前端框架均可) 浏览器兼容:支持现代主流浏览器(Chrome、Ed…
一、使用前提
- 运行环境:任意支持 HTML/CSS/JavaScript 的网页环境(静态 HTML、PHP、Python Web、Vue/React 等前端框架均可)
- 浏览器兼容:支持现代主流浏览器(Chrome、Edge、Firefox、Safari 10+),IE 浏览器不支持(无兼容必要)
- 无额外依赖:无需引入 jQuery、Vue 等第三方库,原生 JS 实现,开箱即用
二、快速部署步骤
步骤 1:复制代码
将完整的弹窗代码(HTML+CSS+JS)复制到你的网页中,推荐放置在 <body> 标签的末尾(</body> 之前),避免阻塞页面加载。
步骤 2:嵌入到网页
场景 1:静态 HTML 文件
直接将代码粘贴到 HTML 文件的 <body> 末尾即可,示例:
预览
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>你的网页标题</title>
<!-- 其他样式/脚本 -->
</head>
<body>
<!-- 你的网页内容 -->
<h1>欢迎访问我的网站</h1>
<!-- 粘贴弹窗代码到这里 -->
<!-- 【弹窗代码开始】 -->
<!-- (复制完整的弹窗HTML+CSS+JS代码) -->
<!-- 【弹窗代码结束】 -->
</body>
</html>
场景 2:动态网页(PHP/Node.js/Java 等)
将弹窗代码作为独立模块嵌入到页面模板的 <body> 末尾,例如 PHP:
运行
<!-- 你的页面内容 -->
<?php include 'header.php'; ?>
<!-- 嵌入弹窗代码 -->
<div id="notice-modal">...</div>
<style>...</style>
<script>...</script>
<?php include 'footer.php'; ?>
步骤 3:测试验证
- 保存文件后,用浏览器打开网页;
- 页面加载后 500 毫秒会自动弹出抽奖弹窗;
- 等待 6 秒倒计时结束后,可点击 “×” 或 “收到啦~辛苦啦💗” 关闭弹窗;
- 关闭后当天刷新页面,弹窗不会重复显示(本地存储记忆功能)。
三、核心功能说明
表格
| 功能点 | 详细说明 |
|---|
| 自动弹出 | 页面加载完成后延迟 500ms 自动显示(仅当天首次访问 / 未关闭过弹窗时) |
| 倒计时限制 | 弹窗打开后 6 秒内关闭按钮不可点击,防止用户立即关闭,提升信息曝光率 |
| 本地存储记忆 | 按域名隔离,关闭弹窗后记录日期,当天内不再重复弹出 |
| 多方式关闭 | 支持 3 种关闭方式:关闭按钮、确认按钮、ESC 键、遮罩层点击(倒计时结束后) |
| 响应式适配 | 移动端自动适配宽度(95%),PC 端最大宽度 500px,适配不同屏幕 |
| 暗黑模式兼容 | 检测页面是否开启暗黑模式(.dark 类),自动切换弹窗样式 |
| 丰富动画效果 | 包含淡入淡出、滑入、心跳、流光、浮动等动画,提升视觉体验 |
| 兼容性处理 | 兼容 localStorage 隐私模式报错,避免代码崩溃 |
四、自定义修改指南
1. 修改文字内容
表格
| 要修改的内容 | 修改位置(代码行 / 区域) |
|---|
| 弹窗标题(饺子) | 找到 <span>💖 饺子有话说~</span>,替换 “饺子” 为任意文字 |
| 弹窗提示语 | 找到 <div>⚠️ 宝子们注意啦!免费抽奖开启啦!</div>,修改提示语内容 |
| 抽奖规则 / 说明 | 找到 .content-block 内的文本,按需修改规则、福利描述等 |
| 确认按钮文字 | 找到 <span id="confirm-text">收到啦~辛苦啦💗</span>,替换按钮文字 |
2. 修改抽奖地址
找到代码中这行链接,替换href和显示文本为你的抽奖地址:
预览
<a href="https://cs.yykbk.com/choujiang" style="color: #fb7299; text-decoration: none; font-weight: 600;">https://cs.yykbk.com/choujiang</a>
3. 修改倒计时时长
找到代码中这行常量,修改数值(单位:秒):
运行
const COUNTDOWN_SECONDS = 6; // 改为3则倒计时3秒,改为10则倒计时10秒
4. 修改弹窗颜色
找到弹窗头部背景渐变代码,替换颜色值(支持 16 进制 / RGB):
预览
<div style="background: linear-gradient(90deg, #fb7299, #fca5c2); ...">
<!-- 例如改为蓝色渐变:linear-gradient(90deg, #409eff, #66b1ff) -->
5. 修改弹窗弹出延迟
找到代码中这行,修改数值(单位:毫秒):
运行
setTimeout(showModal, 500); // 500=0.5秒,改为1000则1秒后弹出,改为0则立即弹出
[hidecontent type="reply"]
<div id="notice-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 999999; display: none; align-items: center; justify-content: center; font-family: 'Microsoft Yahei', 'PingFang SC', sans-serif; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); opacity: 0;">
<div style="width: 90%; max-width: 500px; background: var(--theme-card-bg,#fff); border-radius: 12px; overflow: hidden; box-shadow: 0 12px 32px rgba(0,0,0,0.25); transform: translateY(20px) scale(0.95); border: 1px solid var(--theme-border-color,#eee);">
<div style="background: linear-gradient(90deg, #fb7299, #fca5c2); padding: 18px 24px; color: #fff; font-size: 18px; font-weight: 600; display: flex; justify-content: space-between; align-items: center; position: relative; overflow: hidden;">
<div style="position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); animation: lightFlow 3s ease-in-out infinite;"></div>
<div style="position: absolute; top: 0; right: 0; width: 120px; height: 120px; background: rgba(255,255,255,0.1); border-radius: 50%; transform: translate(40%, -40%); animation: float 6s ease-in-out infinite;"></div>
<span style="animation: textFadeIn 0.8s ease 0.3s forwards, heartbeat 1.5s ease-in-out 1s infinite; opacity: 0; display: inline-block;">💖 饺子有话说~</span>
<button id="close-modal" disabled style="background: rgba(255,255,255,0.2); border: none; color: #fff; font-size: 16px; cursor: not-allowed; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: all 0.2s; animation: btnPop 0.5s ease 0.5s forwards; opacity: 0;">
<span id="close-countdown">6</span>
</button>
</div>
<div style="padding: 28px 24px; color: var(--theme-font-color,#333); line-height: 1.7;">
<div style="font-size: 17px; margin-bottom: 20px; color: var(--theme-font-color,#222); font-weight: 600; text-align: center; animation: textUp 0.6s ease 0.6s forwards, bounce 2s ease-in-out 1.5s infinite; opacity: 0; transform: translateY(10px);">
⚠️ 宝子们注意啦!免费抽奖开启啦!
</div>
<div class="content-block" style="font-size: 15px; color: var(--theme-font-color-light,#555); margin-bottom: 28px; background: var(--theme-card-bg-light,#fdf7fa); padding: 24px 20px; line-height: 2; border-radius: 8px; animation: contentFadeIn 0.8s ease 0.8s forwards, typingBlock 3s ease 1s forwards; opacity: 0; transform: translateY(10px); max-height: 0; overflow: hidden;">
1.每日签到可获得1次免费翻牌机会,限当天有效。<br>
2.免费抽奖来袭!会员、余额、积分天天送,人人可参与!<br>
🔥 本站宠粉福利开启,0 门槛免费抽奖,无套路、不花钱!<br>
✅ 每日免费抽奖次数,登录即可参与<br>
✅ 豪华会员、平台余额、海量积分任性送<br>
✅ 中奖率超高,福利实时到账,不玩虚的<br>
抽奖地址:<a href="https://cs.yykbk.com/choujiang" style="color: #fb7299; text-decoration: none; font-weight: 600;">https://cs.yykbk.com/choujiang</a>
</div>
<div style="text-align: center;">
<button id="confirm-modal" disabled style="background: linear-gradient(90deg, #fb7299, #fca5c2); color: #fff; border: none; padding: 12px 40px; border-radius: 25px; font-size: 15px; cursor: not-allowed; transition: all 0.3s; box-shadow: 0 4px 12px rgba(251, 114, 153, 0.3); font-weight: 500; animation: btnUp 0.6s ease 1s forwards, shake 3s ease-in-out 2s infinite; opacity: 0; transform: translateY(10px);">
<span id="confirm-text">收到啦~辛苦啦💗</span>
<span id="confirm-countdown" style="margin-left: 8px;">(6)</span>
</button>
</div>
</div>
</div>
</div>
<style>
#notice-modal *{box-sizing:border-box;margin:0;padding:0}
@keyframes modalFadeIn{from{opacity:0}to{opacity:1}}
@keyframes modalSlideIn{from{transform:translateY(20px) scale(0.95);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}
@keyframes textFadeIn{from{opacity:0;transform:scale(0.95)}to{opacity:1;transform:scale(1)}}
@keyframes textUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@keyframes contentFadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@keyframes btnPop{from{opacity:0;transform:scale(0.8)}70%{transform:scale(1.1)}to{opacity:1;transform:scale(1)}}
@keyframes btnUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@keyframes breathe{0%{transform:scale(1)}50%{transform:scale(1.03)}100%{transform:scale(1)}}
@keyframes float{0%{transform:translate(40%, -40%) rotate(0deg)}50%{transform:translate(35%, -35%) rotate(10deg)}100%{transform:translate(40%, -40%) rotate(0deg)}}
@keyframes heartbeat{0%{transform:scale(1)}10%{transform:scale(1.05)}20%{transform:scale(1)}30%{transform:scale(1.05)}40%{transform:scale(1)}}
@keyframes lightFlow{0%{left:-100%}100%{left:200%}}
@keyframes bounce{0%{transform:translateY(0)}5%{transform:translateY(-5px)}10%{transform:translateY(0)}15%{transform:translateY(-3px)}20%{transform:translateY(0)}}
@keyframes typingBlock{from{max-height:0}to{max-height:400px}}
@keyframes shake{0%{transform:translateX(0)}2%{transform:translateX(-2px)}4%{transform:translateX(2px)}6%{transform:translateX(-2px)}8%{transform:translateX(2px)}10%{transform:translateX(0)}}
#close-modal:not([disabled]):hover{background:rgba(255,255,255,0.3)!important;transform:scale(1.1)!important;cursor: pointer;}
#confirm-modal:not([disabled]):hover{animation: breathe 2s ease-in-out infinite, shake 3s ease-in-out 2s infinite!important;transform:scale(1.08)!important;box-shadow:0 6px 16px rgba(251, 114, 153, 0.4)!important;cursor: pointer;}
#confirm-modal:active{transform:scale(0.98)!important}
#close-modal[disabled]{opacity: 0.7!important;}
#confirm-modal[disabled]{opacity: 0.8!important;}
@media (max-width:480px){#notice-modal>div{width:95%!important}#confirm-modal{width:100%!important}.content-block{padding:20px 16px!important;line-height:1.9!important}}
/* 暗黑模式全局适配 */
.dark #notice-modal>div{background: #1f1f1f!important; border-color: #333!important;}
.dark #notice-modal .content-block{background: #2a2a2a!important; color: #ddd!important;}
.dark #notice-modal [style*="color: var(--theme-font-color,#333)"]{color: #eee!important;}
.dark #notice-modal [style*="color: var(--theme-font-color,#222)"]{color: #fff!important;}
</style>
<script>
document.addEventListener('DOMContentLoaded',function(){
// 定义弹窗相关元素
const modal = document.getElementById('notice-modal');
const closeBtn = document.getElementById('close-modal');
const confirmBtn = document.getElementById('confirm-modal');
const modalContent = modal.querySelector('div');
const closeCountdown = document.getElementById('close-countdown');
const confirmCountdown = document.getElementById('confirm-countdown');
const confirmText = document.getElementById('confirm-text');
// 关闭倒计时时长(秒)
const COUNTDOWN_SECONDS = 6;
// 倒计时定时器
let countdownTimer = null;
// 标记弹窗是否已显示,防止重复执行
let isModalShown = false;
// ========== 核心优化:域名隔离的本地存储Key ==========
// 获取当前域名(自动适配,无需手动修改)
function getCurrentDomain() {
return window.location.hostname;
}
// 生成带域名标识的存储Key(确保不同域名隔离)
function getStorageKey() {
const domain = getCurrentDomain();
return `noticeModalClosedDate_${domain.replace(/\./g, '_')}`;
}
// 获取当前日期(格式:YYYY-MM-DD)
function getCurrentDate() {
const date = new Date();
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
}
// 安全操作localStorage(兼容隐私模式)
function safeLocalStorageOperation(operation, key, value = null) {
try {
switch(operation) {
case 'get': return localStorage.getItem(key);
case 'set': localStorage.setItem(key, value); break;
case 'remove': localStorage.removeItem(key); break;
}
} catch (e) {
console.warn('LocalStorage不可用,弹窗记忆功能暂时失效:', e);
return null;
}
}
// 检查当前域名下,当天是否已关闭过弹窗
function hasClosedToday() {
const storageKey = getStorageKey();
const closedDate = safeLocalStorageOperation('get', storageKey);
return closedDate === getCurrentDate();
}
// 记录当前域名下,弹窗已关闭(存入本地存储)
function markAsClosedToday() {
const storageKey = getStorageKey();
safeLocalStorageOperation('set', storageKey, getCurrentDate());
}
// 重置倒计时的函数
function resetCountdown() {
if (!closeBtn || !confirmBtn) return;
closeBtn.disabled = true;
confirmBtn.disabled = true;
closeBtn.style.cursor = 'not-allowed';
confirmBtn.style.cursor = 'not-allowed';
let remainingSeconds = COUNTDOWN_SECONDS;
closeCountdown.textContent = remainingSeconds;
confirmCountdown.textContent = `(${remainingSeconds})`;
if (countdownTimer) clearInterval(countdownTimer);
countdownTimer = setInterval(() => {
remainingSeconds--;
closeCountdown.textContent = remainingSeconds;
confirmCountdown.textContent = `(${remainingSeconds})`;
if (remainingSeconds <= 0) {
clearInterval(countdownTimer);
closeBtn.disabled = false;
confirmBtn.disabled = false;
closeBtn.style.cursor = 'pointer';
confirmBtn.style.cursor = 'pointer';
closeCountdown.textContent = '×';
confirmCountdown.remove();
closeBtn.style.opacity = '1';
confirmBtn.style.opacity = '1';
}
}, 1000);
}
// 显示弹窗的函数
function showModal() {
// 防止重复显示
if (isModalShown || hasClosedToday() || !modal) return;
isModalShown = true;
modal.style.display = 'flex';
modal.style.animation = 'modalFadeIn 0.4s ease forwards';
modalContent.style.animation = 'modalSlideIn 0.4s ease 0.1s forwards';
resetCountdown();
}
// 关闭弹窗的函数
function closeModal() {
if (!modal) return;
// 记录关闭状态
markAsClosedToday();
modal.style.animation = 'modalFadeIn 0.3s ease reverse forwards';
modalContent.style.animation = 'modalSlideIn 0.3s ease reverse forwards';
setTimeout(() => {
modal.style.display = 'none';
isModalShown = false;
if (countdownTimer) clearInterval(countdownTimer);
}, 300);
}
// 绑定关闭事件
if(closeBtn) closeBtn.addEventListener('click', closeModal);
if(confirmBtn) confirmBtn.addEventListener('click', closeModal);
// 遮罩层点击关闭(仅倒计时结束后)
modal.addEventListener('click', function(e) {
if(e.target === modal && !closeBtn?.disabled) {
closeModal();
}
});
// ESC键关闭弹窗
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && isModalShown) {
closeModal();
}
});
// 页面加载后延迟显示弹窗
if (!hasClosedToday()) {
setTimeout(showModal, 500);
}
});
</script>
[/hidecontent]