Files
wordpress-theme-aksrt/assets/js/site-notice.js
T
kate522 1f4a39d8f8 feat(runtime): 全站前端脚本统一接入 AksrtFrontend 全局 DOM 生命周期
- rehydrate.js 新增 boot()/aksrt:ready 事件,支持 boot 后晚注册立即以 init 触发
- aksrt-runtime.js 初始加载改走 AksrtFrontend.boot,tooltip/倒计时注册为组件
- 约 30 个前端脚本(首页、评论、支付、路由、页面叶子、widgets)
  从直接 DOMContentLoaded 迁移为 AksrtFrontend.register,并加幂等标记
- section-navs 依赖改为 aksrt-runtime,保证注册时序
- 清理死代码:删除孤儿 loader.js/main.js 及 runtime/page-navs 遗留副本
- loader.js 移除已迁移模块的 tbquire 路径映射,main.js 相应瘦身
- build-public-assets.mjs 增加 runtime/main.min.js 自动压缩步骤
- 新增 4 个契约测试(homepage-dom/rehydrate-runtime/global-dom-init/
  public-bundle-parity),3 个既有 harness 适配注册表初始化方式
2026-09-02 21:48:56 +08:00

96 lines
2.9 KiB
JavaScript

/**
* AKSRT Site Notice — Popup notice with cookie-based frequency control
*
* Identity-based policy check is done server-side (PHP).
* JS only handles: show/hide animation, cookie dismissal, expiry.
*
* @package AKSRT
*/
(function () {
'use strict';
window.AksrtFrontend.register('aksrt-site-notice', function (root) {
root = root || document;
var el = root.nodeType === 1 && root.matches('#aksrt-site-notice') ? root : root.querySelector('#aksrt-site-notice');
if (!el || el.dataset.aksrtNoticeBound === '1') return;
el.dataset.aksrtNoticeBound = '1';
// 弹窗周期(小时),0=永不过期
var expiresHours = parseInt(el.dataset.expires || '24', 10) || 0;
var cookieName = 'aksrt_notice_seen';
function getCookie(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
return match ? decodeURIComponent(match[2]) : null;
}
function setCookie(name, value, days) {
var expires = '';
if (days) {
var date = new Date();
date.setTime(date.getTime() + days * 86400000);
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + encodeURIComponent(value) + expires + '; path=/; SameSite=Lax';
}
function shouldShow() {
if (expiresHours === 0) return true; // 永不过期,总是显示
var seen = getCookie(cookieName);
if (!seen) return true;
var seenTs = parseInt(seen, 10);
if (!seenTs || seenTs <= 0) return true;
var now = Math.floor(Date.now() / 1000);
return (now - seenTs) >= (expiresHours * 3600);
}
function dismiss() {
// 写入当前时间戳
var days = expiresHours > 0 ? Math.ceil(expiresHours / 24) : 365;
setCookie(cookieName, String(Math.floor(Date.now() / 1000)), days);
close();
}
function close() {
el.style.opacity = '0';
setTimeout(function () {
el.style.display = 'none';
}, 300);
}
function show() {
el.style.display = '';
el.style.opacity = '0';
requestAnimationFrame(function () {
el.style.transition = 'opacity 0.3s';
el.style.opacity = '1';
});
}
// Bind events
var closeBtn = el.querySelector('.aksrt-site-notice__close');
var overlay = el.querySelector('.aksrt-site-notice__overlay');
// 所有 dismiss 按钮(包括 data-dismiss="notice" 的按钮和链接)
var dismissBtns = el.querySelectorAll('[data-dismiss="notice"]');
if (closeBtn) closeBtn.addEventListener('click', dismiss);
if (overlay) overlay.addEventListener('click', dismiss);
for (var i = 0; i < dismissBtns.length; i++) {
dismissBtns[i].addEventListener('click', dismiss);
}
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && el.style.display !== 'none') {
dismiss();
}
});
// Show on load if needed
if (shouldShow()) {
// Delay slightly so it doesn't flash on fast navigations
setTimeout(show, 500);
}
});
})();