JS 底部弹窗实现 Cookie 隐私权限获取
寻梦xunm| 66| 网络收集
1天前

实现 Cookie 隐私权限弹窗的核心是「底部固定显示 + 权限选择逻辑 + Cookie 状态存储」,确保用户首次访问时弹窗,选择后永久记忆,同时兼顾安全性和兼容性。(1)Cookie 操作安全
Screenshot_2025_1119_083112.png

<!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">&times;</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>
  • 编码处理:使用 encodeURIComponent / decodeURIComponent 对 Cookie 名称和值编码,避免特殊字符(如空格、&、=)导致的存储异常。
  • 域名与路径控制:设置 domain 为顶级域名(如 .xxx.com )确保子域名共享权限状态; path='/' 确保全站 Cookie 生效,避免局部路径无法读取的问题。
  • 过期时间管理:权限状态默认存储 365 天,非必要 Cookie 按需设置短期有效期(如主题 Cookie 30 天),减少无效 Cookie 占用。

(2)用户体验与合规性

  • 分层权限选择:支持「仅必要」和「全部接受」,符合 GDPR、CCPA 等隐私法规要求,避免强制同意。
  • 详情透明化:新增权限详情弹窗,明确告知不同类型 Cookie 的用途,提升用户信任度。
  • 移动端适配:弹窗固定底部、响应式宽度,按钮自适应布局,适配手机、平板等设备。

(3)性能优化

  • 脚本异步加载:第三方分析脚本使用 async=true ,避免阻塞页面 DOM 渲染,提升首屏加载速度。
  • 重复加载防护:加载分析脚本前检查是否已存在,避免多次执行导致的性能损耗和数据统计异常。
  • 状态优先判断:页面初始化时先读取 Cookie 状态,未选择时才显示弹窗,减少不必要的 DOM 操作。
none
0 赞 or 打赏
喜欢就打赏一点
微信 支付宝
下一篇

没有了

站内搜索
Q Q:1340326824
邮箱:vipshiyi@qq.com
QQ群:422720328
本站没得会员制度,所有资源都有白嫖的方法,且用且珍惜! 本站相关资源来自互联网用户收集发布,仅供用于学习和交流。 如有侵权之处,请联系站长并出示相关证明以便删除,敬请谅解!

我的音乐