给你的网站加上一个弹窗公告

2025-09-23 13:45:07 其他cms源码 小编

效果展示


图片[1]-给你的网站加上一个弹窗公告-IT技术博客


公告能够在不同设备自适应显示

实现方法

1.在网站目录创建文件 itjs.js ,并且粘贴以下代码到你刚刚创建的这个JS文件里面。

文件名称可以自定义,引用的时候只需要改成你自定义的文件名称即可,如果是小白就跟着教程走吧。

// 公告弹窗
(function () {
   function showAnnounce() {
       const lastClose = localStorage.getItem('announceLastClose');
       if (!lastClose) return true;
       const oneDayAgo = Date.now() - (24 * 60 * 60 * 1000);
       return new Date(lastClose).getTime() < oneDayAgo;
   }

   if (!showAnnounce()) return;

   const cfg = window.announceConfig || {
       title: "公告通知",
       items: [
           {
               icon: "news",
               title: "最新公告",
               content: "本平台新增多项安全验证功能,建议您及时完善个人信息。"
           },
           {
               icon: "update",
               title: "功能更新",
               content: "新版移动端已上线,支持离线模式和数据同步功能。"
           }
       ],
       noShowText: "一天内不再显示",
       laterText: "稍后提醒",
       okText: "我知道了",
       mainColor: "#3b82f6",
       maxW: "500px",
       z: 9999
   };

   function addStyles() {
       const style = document.createElement('style');
       style.textContent = `
           .announce-mask {
               position: fixed;
               top: 0;
               left: 0;
               right: 0;
               bottom: 0;
               background: rgba(0,0,0,0.5);
               z-index: ${cfg.z - 1};
               opacity: 0;
               visibility: hidden;
               transition: opacity 0.3s;
               backdrop-filter: blur(4px);
           }
           
           .announce-mask.show {
               opacity: 1;
               visibility: visible;
           }
           
           .announce-box {
               position: fixed;
               top: 50%;
               left: 50%;
               transform: translate(-50%, -50%) scale(0.95);
               background: white;
               border-radius: 10px;
               max-width: ${cfg.maxW};
               width: calc(100% - 30px);
               box-shadow: 0 5px 20px rgba(0,0,0,0.1);
               z-index: ${cfg.z};
               overflow: hidden;
               opacity: 0;
               visibility: hidden;
               transition: all 0.3s;
           }
           
           .announce-box.show {
               opacity: 1;
               visibility: visible;
               transform: translate(-50%, -50%) scale(1);
           }
           
           .announce-head {
               background: ${cfg.mainColor};
               color: white;
               padding: 15px 20px;
               display: flex;
               align-items: center;
               justify-content: space-between;
           }
           
           .announce-title {
               margin: 0;
               font-size: 1.2rem;
               display: flex;
               align-items: center;
               gap: 10px;
           }
           
           .announce-close {
               background: none;
               border: none;
               color: white;
               font-size: 1.5rem;
               cursor: pointer;
               width: 30px;
               height: 30px;
               display: flex;
               align-items: center;
               justify-content: center;
               border-radius: 50%;
           }
           
           .announce-close:hover {
               background: rgba(255,255,255,0.2);
           }
           
           .announce-body {
               padding: 20px;
           }
           
           .announce-list {
               margin: 0;
               padding: 0;
               list-style: none;
           }
           
           .announce-item {
               display: flex;
               gap: 12px;
               padding: 15px 0;
               border-bottom: 1px solid #f1f5f9;
           }
           
           .announce-item:last-child {
               border-bottom: none;
               padding-bottom: 0;
           }
           
           .announce-icon {
               width: 40px;
               height: 40px;
               border-radius: 8px;
               display: flex;
               align-items: center;
               justify-content: center;
               flex-shrink: 0;
           }
           
           .announce-icon.news {
               background: #e0f2fe;
           }
           
           .announce-icon.update {
               background: #e6f7ee;
           }
           
           .announce-icon svg {
               width: 20px;
               height: 20px;
           }
           
           .announce-icon.news svg {
               fill: #0284c7;
           }
           
           .announce-icon.update svg {
               fill: #059669;
           }
           
           .announce-text {
               flex: 1;
           }
           
           .announce-item-title {
               margin: 0 0 5px 0;
               font-size: 1rem;
               font-weight: 600;
               color: #1e293b;
           }
           
           .announce-item-desc {
               margin: 0;
               font-size: 0.9rem;
               color: #64748b;
               line-height: 1.5;
           }
           
           .announce-option {
               padding: 0 20px 15px;
           }
           
           .announce-check {
               display: flex;
               align-items: center;
               gap: 8px;
               cursor: pointer;
           }
           
           .announce-checkbox {
               width: 18px;
               height: 18px;
               accent-color: ${cfg.mainColor};
           }
           
           .announce-check-label {
               font-size: 0.9rem;
               color: #64748b;
           }
           
           .announce-foot {
               padding: 15px 20px;
               border-top: 1px solid #f1f5f9;
               display: flex;
               gap: 10px;
           }
           
           .announce-btn {
               padding: 9px 15px;
               border: none;
               border-radius: 6px;
               font-size: 0.9rem;
               cursor: pointer;
               flex: 1;
               transition: all 0.2s;
           }
           
           .announce-btn.later {
               background: #f1f5f9;
               color: #475569;
           }
           
           .announce-btn.later:hover {
               background: #e2e8f0;
           }
           
           .announce-btn.ok {
               background: ${cfg.mainColor};
               color: white;
           }
           
           .announce-btn.ok:hover {
               background: ${shadeColor(cfg.mainColor, -15)};
           }
           
           @media (max-width: 480px) {
               .announce-foot {
                   flex-direction: column;
               }
           }
       `;
       document.head.appendChild(style);
   }

   function shadeColor(color, percent) {
       let R = parseInt(color.substring(1, 3), 16);
       let G = parseInt(color.substring(3, 5), 16);
       let B = parseInt(color.substring(5, 7), 16);

       R = parseInt(R * (100 + percent) / 100);
       G = parseInt(G * (100 + percent) / 100);
       B = parseInt(B * (100 + percent) / 100);

       R = R < 255 ? R : 255;
       G = G < 255 ? G : 255;
       B = B < 255 ? B : 255;

       R = Math.round(R);
       G = Math.round(G);
       B = Math.round(B);

       const RR = (R.toString(16).length === 1) ? "0" + R.toString(16) : R.toString(16);
       const GG = (G.toString(16).length === 1) ? "0" + G.toString(16) : G.toString(16);
       const BB = (B.toString(16).length === 1) ? "0" + B.toString(16) : B.toString(16);

       return "#" + RR + GG + BB;
   }

   function closeAnnounce(mask, box, noShow) {
       mask.classList.remove('show');
       box.classList.remove('show');

       if (noShow) {
           localStorage.setItem('announceLastClose', new Date().toISOString());
       }

       setTimeout(() => {
           mask.remove();
           box.remove();
       }, 300);
   }

   function createItems(container) {
       const list = document.createElement('ul');
       list.className = 'announce-list';

       cfg.items.forEach(item => {
           const li = document.createElement('li');
           li.className = 'announce-item';

           const icon = document.createElement('div');
           icon.className = `announce-icon ${item.icon}`;

           let svg = '';
           if (item.icon === 'news') {
               svg = `
                   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                       <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zM7 7h5v5H7zm5 7H7v2h5zm2-4h2v2h-2zm0 4h2v2h-2z"/>
                   </svg>
               `;
           } else if (item.icon === 'update') {
               svg = `
                   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                       <path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8zm-2 8v3l4-4-4-4v3H6v2h4z"/>
                   </svg>
               `;
           }

           icon.innerHTML = svg;

           const text = document.createElement('div');
           text.className = 'announce-text';

           const title = document.createElement('h4');
           title.className = 'announce-item-title';
           title.textContent = item.title;

           const desc = document.createElement('p');
           desc.className = 'announce-item-desc';
           desc.textContent = item.content;

           text.appendChild(title);
           text.appendChild(desc);

           li.appendChild(icon);
           li.appendChild(text);
           list.appendChild(li);
       });

       container.appendChild(list);
   }

   function createAnnounce() {
       const mask = document.createElement('div');
       mask.className = 'announce-mask';

       const box = document.createElement('div');
       box.className = 'announce-box';

       const head = document.createElement('div');
       head.className = 'announce-head';

       const title = document.createElement('h3');
       title.className = 'announce-title';
       title.innerHTML = `
           <svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
               <path d="M12 2c5.51 0 10 4.49 10 10s-4.49 10-10 10S2 17.51 2 12 6.49 2 12 2zm0 2c-4.41 0-8 3.59-8 8s3.59 8 8 8 8-3.59 8-8-3.59-8-8-8zm-1 3h2v6h-2zm0 8h2v2h-2z"/>
           </svg>
           ${cfg.title}
       `;

       const closeBtn = document.createElement('button');
       closeBtn.className = 'announce-close';
       closeBtn.textContent = '×';
       closeBtn.addEventListener('click', () => {
           closeAnnounce(mask, box, false);
       });

       head.appendChild(title);
       head.appendChild(closeBtn);

       const body = document.createElement('div');
       body.className = 'announce-body';
       createItems(body);

       const option = document.createElement('div');
       option.className = 'announce-option';

       const check = document.createElement('label');
       check.className = 'announce-check';

       const checkbox = document.createElement('input');
       checkbox.type = 'checkbox';
       checkbox.className = 'announce-checkbox';
       checkbox.id = 'noShow';

       const label = document.createElement('span');
       label.className = 'announce-check-label';
       label.textContent = cfg.noShowText;

       check.appendChild(checkbox);
       check.appendChild(label);
       option.appendChild(check);

       const foot = document.createElement('div');
       foot.className = 'announce-foot';

       const laterBtn = document.createElement('button');
       laterBtn.className = 'announce-btn later';
       laterBtn.textContent = cfg.laterText;
       laterBtn.addEventListener('click', () => {
           closeAnnounce(mask, box, false);
       });

       const okBtn = document.createElement('button');
       okBtn.className = 'announce-btn ok';
       okBtn.textContent = cfg.okText;
       okBtn.addEventListener('click', () => {
           closeAnnounce(mask, box, checkbox.checked);
       });

       foot.appendChild(laterBtn);
       foot.appendChild(okBtn);

       box.appendChild(head);
       box.appendChild(body);
       box.appendChild(option);
       box.appendChild(foot);

       document.body.appendChild(mask);
       document.body.appendChild(box);

       setTimeout(() => {
           mask.classList.add('show');
           box.classList.add('show');
       }, 100);

       mask.addEventListener('click', (e) => {
           if (e.target === mask) {
               closeAnnounce(mask, box, false);
           }
       });

       document.addEventListener('keydown', (e) => {
           if (e.key === 'Escape') {
               closeAnnounce(mask, box, false);
           }
       });
   }

   if (document.readyState === 'loading') {
       document.addEventListener('DOMContentLoaded', () => {
           addStyles();
           createAnnounce();
       });
   } else {
       addStyles();
       createAnnounce();
   }
})();


图片[2]-给你的网站加上一个弹窗公告-IT技术博客


这里的文本按照你的需求进行更改,其中 icon 为图标名称,小白切勿随意修改,否则图标将无法正常显示。

2.在需要弹窗公告的页面加上以下代码即可实现弹窗公告功能。

一般加在主页,也可以加在全局文件实现全部页面弹出公告,具体根据你的实际需求。

  <script src="itjs.js"></script>

关于这段代码放在页面哪里比较好:

1.body标签的末尾(推荐)

注意:不是body标签后面!在body标签里面,放在</body>标签前。

优点:此时页面 DOM 加载完成后再执行公告脚本,避免因 DOM 未就绪导致的问题,同时不阻塞页面渲染
缺点:公告弹窗会比放在head中稍晚出现


2.head标签内,配合defer属性

<script src="itjs.js" defer></script>

优点:提前加载脚本,但会等待 DOM 就绪后再执行,不阻塞页面渲染
缺点:需要浏览器支持defer属性(现代浏览器都支持)


3.head标签内,不使用任何属性(不推荐)
缺点:会阻塞页面渲染,直到脚本加载并执行完成,影响页面加载速度


综合考虑,推荐放在body标签末尾,这种方式既能保证脚本正常运行,又不会影响页面的加载性能,公告弹窗会在页面内容渲染完成后适时出现,给用户更好的体验。
如果希望公告尽可能早地出现,但又不影响页面加载,可以选择第二种方式(head中加defer)

代码说明

模块化设计:采用立即执行函数表达式 (IIFE) 封装,避免全局变量污染,内部功能划分清晰(样式添加、元素创建、事件处理等)

响应式设计:在移动设备上自动调整布局,支持点击遮罩层、关闭按钮、ESC 键等多种关闭方式。

样式隔离:公告代码通过独特的类名前缀(announce-)避免样式冲突。


声明:某某网站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系[email protected]
广告
广告
链接占位符:{promotion.url.123},链接占位符:{promotion.pic.123},文字:{promotion.title.123}