JS 底部弹窗实现 Cookie 隐私权限获取
1天前
实现 Cookie 隐私权限弹窗的核心是「底部固定显示 + 权限选择逻辑 + Cookie 状态存储」,确保用户首次访问时弹窗,选择后永久记忆,同时兼顾安全性和兼容性。(1)Cookie 操作安全
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cookie 隐私权限弹窗</title>
<style>
/* 底部弹窗样式:固定定位+遮罩层,兼顾移动端适配 */
.cookie-modal-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9998;
display: none;
}
.cookie-modal {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
max-width: 768px;
margin: 0 auto;
background: #fff;
border-radius: 12px 12px 0 0;
padding: 20px;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
z-index: 9999;
display: none;
}
.cookie-modal.show {
display: block;
}
.cookie-modal-mask.show {
display: block;
}
.cookie-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 10px;
color: #333;
}
.cookie-desc {
font-size: 14px;
color: #666;
margin-bottom: 15px;
line-height: 1.5;
}
.cookie-link {
color: #1677ff;
text-decoration: underline;
cursor: pointer;
}
.cookie-btns {
display: flex;
gap: 10px;
margin-top: 20px;
}
.cookie-btn {
flex: 1;
padding: 10px 0;
border-radius: 8px;
border: none;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
.cookie-btn-reject {
background: #f5f5f5;
color: #666;
}
.cookie-btn-reject:hover {
background: #e5e5e5;
}
.cookie-btn-accept {
background: #1677ff;
color: #fff;
}
.cookie-btn-accept:hover {
background: #0f62fe;
}
/* 权限详情弹窗(可选) */
.cookie-detail-modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 500px;
background: #fff;
border-radius: 12px;
padding: 20px;
z-index: 10000;
display: none;
}
.cookie-detail-modal.show {
display: block;
}
.cookie-detail-close {
position: absolute;
top: 15px;
right: 15px;
font-size: 20px;
cursor: pointer;
color: #666;
}
</style>
</head>
<body>
<!-- 遮罩层 -->
<div class="cookie-modal-mask" id="cookieMask"></div>
<!-- Cookie 权限主弹窗 -->
<div class="cookie-modal" id="cookieModal">
<h3 class="cookie-title">隐私政策与 Cookie 通知</h3>
<p class="cookie-desc">
我们使用 Cookie 来提升您的浏览体验、分析网站流量,并为您提供个性化内容。
您可以选择「仅必要 Cookie」或「全部接受」,也可点击 <span class="cookie-link" id="showDetail">详情</span> 了解更多。
</p>
<div class="cookie-btns">
<button class="cookie-btn cookie-btn-reject" id="rejectCookie">仅必要 Cookie</button>
<button class="cookie-btn cookie-btn-accept" id="acceptCookie">全部接受</button>
</div>
</div>
<!-- Cookie 权限详情弹窗(可选) -->
<div class="cookie-detail-modal" id="cookieDetailModal">
<span class="cookie-detail-close" id="closeDetail">×</span>
<h3 class="cookie-title">Cookie 权限详情</h3>
<p class="cookie-desc"><strong>必要 Cookie</strong>:保障网站基础功能运行(如登录状态),无法禁用。</p>
<p class="cookie-desc"><strong>功能 Cookie</strong>:记住您的偏好(如主题设置),提升使用体验。</p>
<p class="cookie-desc"><strong>分析 Cookie</strong>:统计访问数据、优化网站性能,不含个人敏感信息。</p>
</div>
<script>
// 1. DOM 元素获取
const cookieMask = document.getElementById('cookieMask');
const cookieModal = document.getElementById('cookieModal');
const acceptBtn = document.getElementById('acceptCookie');
const rejectBtn = document.getElementById('rejectCookie');
const showDetailBtn = document.getElementById('showDetail');
const closeDetailBtn = document.getElementById('closeDetail');
const detailModal = document.getElementById('cookieDetailModal');
// 2. Cookie 核心工具函数(安全+兼容)
const CookieUtil = {
// 设置 Cookie:支持过期时间(天)、路径、域名,默认365天有效期
set(name, value, days = 365, path = '/', domain = '') {
let expires = '';
if (days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = `; expires=${date.toUTCString()}`;
}
// 域名可选:非顶级域名需指定(如 '.xxx.com'),确保子域名共享 Cookie
const domainStr = domain ? `; domain=${domain}` : '';
// 写入 Cookie:路径默认 '/',确保全站生效
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${expires}${domainStr}; path=${path}`;
},
// 获取 Cookie:根据名称读取值,处理编码
get(name) {
const nameEQ = `${encodeURIComponent(name)}=`;
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
if (cookie.indexOf(nameEQ) === 0) {
return decodeURIComponent(cookie.substring(nameEQ.length));
}
}
return null; // 未找到返回 null
},
// 删除 Cookie:将过期时间设为过去,实现删除
remove(name, path = '/', domain = '') {
this.set(name, '', -1, path, domain);
}
};
// 3. 权限逻辑处理
class CookiePermission {
constructor() {
// 存储 Cookie 权限标识的 key(建议加项目前缀,避免冲突)
this.permissionKey = 'site_cookie_permission';
// 初始化:检查是否已存在权限状态
this.init();
}
// 初始化:判断是否显示弹窗
init() {
const permission = CookieUtil.get(this.permissionKey);
if (!permission) {
// 未选择权限:显示弹窗和遮罩
cookieMask.classList.add('show');
cookieModal.classList.add('show');
} else {
// 已选择权限:执行对应逻辑(如加载分析脚本)
this.handlePermission(permission);
}
}
// 处理用户选择的权限(accept:全部接受;reject:仅必要)
handlePermission(permission) {
switch (permission) {
case 'accept':
// 全部接受:初始化功能、分析类 Cookie/脚本
this.initAllCookies();
break;
case 'reject':
// 仅必要:删除已存在的非必要 Cookie,不加载额外脚本
this.clearNonNecessaryCookies();
break;
default:
break;
}
}
// 全部接受:初始化非必要 Cookie(示例:主题偏好、分析标识)
initAllCookies() {
// 示例1:功能 Cookie - 记住用户主题偏好(默认浅色)
CookieUtil.set('site_theme', 'light', 30);
// 示例2:分析 Cookie - 生成唯一访问标识(用于统计)
CookieUtil.set('site_visit_id', this.generateRandomStr(), 7);
// 示例3:加载第三方分析脚本(如百度统计、Google Analytics)
this.loadAnalyticsScript();
}
// 仅必要:清除非必要 Cookie(示例:主题、分析相关)
clearNonNecessaryCookies() {
CookieUtil.remove('site_theme');
CookieUtil.remove('site_visit_id');
// 若已加载分析脚本,可执行关闭逻辑(如百度统计的暂停)
this.stopAnalytics();
}
// 生成随机访问标识(用于分析 Cookie,避免重复)
generateRandomStr(length = 16) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let str = '';
for (let i = 0; i < length; i++) {
str += chars.charAt(Math.floor(Math.random() * chars.length));
}
return str;
}
// 加载第三方分析脚本(示例:百度统计,实际项目替换为自身脚本)
loadAnalyticsScript() {
// 避免重复加载:检查脚本是否已存在
if (document.getElementById('baidu-analytics')) return;
const script = document.createElement('script');
script.id = 'baidu-analytics';
script.src = 'https://hm.baidu.com/hm.js?您的百度统计ID';
script.async = true; // 异步加载,不阻塞页面渲染
document.body.appendChild(script);
}
// 停止分析脚本(示例:百度统计暂停统计)
stopAnalytics() {
if (window._hmt) {
_hmt.push(['_pause']); // 百度统计暂停接口
}
}
// 用户选择权限:存储状态并隐藏弹窗
setPermission(permission) {
// 存储权限状态(accept/reject)
CookieUtil.set(this.permissionKey, permission);
// 处理权限逻辑
this.handlePermission(permission);
// 隐藏弹窗和遮罩
cookieMask.classList.remove('show');
cookieModal.classList.remove('show');
}
}
// 4. 实例化并绑定事件
const cookiePermission = new CookiePermission();
// 接受全部权限
acceptBtn.addEventListener('click', () => {
cookiePermission.setPermission('accept');
});
// 仅必要权限
rejectBtn.addEventListener('click', () => {
cookiePermission.setPermission('reject');
});
// 显示权限详情
showDetailBtn.addEventListener('click', () => {
detailModal.classList.add('show');
});
// 关闭权限详情
closeDetailBtn.addEventListener('click', () => {
detailModal.classList.remove('show');
});
// 点击遮罩关闭详情弹窗
cookieMask.addEventListener('click', () => {
detailModal.classList.remove('show');
});
</script>
</body>
</html>
(2)用户体验与合规性
(3)性能优化
没有了