diff --git a/assets/app.js b/assets/app.js index 7a1a530..cafdfe3 100644 --- a/assets/app.js +++ b/assets/app.js @@ -801,46 +801,30 @@ } } - /* ---------- 顶栏软件抽屉(右上角汉堡按钮) ---------- - * 原来「选择软件」平铺在列表上方占一整行,软件一多就把内容往下推。 - * 现在收进抽屉:点击展开 / 再次点击收起 / 点外部关闭 / Esc 关闭。 - * 用 hidden 属性而非纯 class,保证无 JS 时抽屉默认不显示(不会闪一下)。 */ + /* ---------- 顶栏软件下拉菜单(右上角三横线) ---------- + * 极简:点了就展开一个小浮窗,点外面 / Esc 就关。 + * 不做遮罩、不锁背景滚动 —— 那套是侧边栏的做法,下拉菜单不需要。 */ function bindSoftwarePanel() { var btn = document.getElementById('swToggle'); var panel = document.getElementById('swPanel'); - var mask = document.getElementById('swMask'); if (!btn || !panel) { return; } - function open() { - panel.hidden = false; - if (mask) { mask.hidden = false; } - btn.setAttribute('aria-expanded', 'true'); - document.body.style.overflow = 'hidden'; // 抽屉开着时锁住背景滚动 - } function close() { panel.hidden = true; - if (mask) { mask.hidden = true; } btn.setAttribute('aria-expanded', 'false'); - document.body.style.overflow = ''; - } - function toggle() { - if (panel.hidden) { open(); } else { close(); } } btn.addEventListener('click', function (e) { e.stopPropagation(); - toggle(); + if (panel.hidden) { + panel.hidden = false; + btn.setAttribute('aria-expanded', 'true'); + } else { + close(); + } }); - // 点遮罩关闭(遮罩就是「下面的内容」,点了就是点外部) - if (mask) { - mask.addEventListener('click', function (e) { - e.stopPropagation(); - close(); - }); - } - - // 点面板内部不算点外部 + // 点菜单内部不算点外面 panel.addEventListener('click', function (e) { e.stopPropagation(); }); document.addEventListener('click', function () { @@ -850,11 +834,6 @@ document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !panel.hidden) { close(); btn.focus(); } }); - - // 转到别的页面时把滚动锁解掉,避免返回后页面不能滚 - window.addEventListener('pagehide', function () { - document.body.style.overflow = ''; - }); } /* ---------- 邮件测试发送(后台设置页) ---------- */ diff --git a/assets/style.css b/assets/style.css index fc31624..dea9d37 100644 --- a/assets/style.css +++ b/assets/style.css @@ -33,7 +33,7 @@ p{margin:8px 0} border-bottom:1px solid var(--line); /* 软件抽屉是 absolute + top:100%,需要它来做定位参照,否则会跑到页面最上面 */ } -.topbar .wrap{display:flex; align-items:center; gap:14px; height:66px} +.topbar .wrap{display:flex; align-items:center; gap:14px; height:66px; position:relative} .topbar .brand-mini{display:flex; align-items:center; gap:10px; font-weight:700; font-size:17px; color:var(--fg); min-width:0} .topbar .brand-mini:hover{text-decoration:none; color:var(--fg)} /* 顶栏里的软件标识:17px 字 + 32px 图标 —— @@ -47,64 +47,65 @@ p{margin:8px 0} .topbar .brand-mini .sw-badge{gap:7px} } -/* ---------- 右上角汉堡按钮 + 软件抽屉 ---------- */ +/* ---------- 右上角三横线按钮 + 下拉菜单 ---------- */ .sw-toggle{ - flex:none; width:40px; height:40px; padding:0; margin-left:2px; - display:inline-flex; flex-direction:column; align-items:center; justify-content:center; gap:5px; - background:transparent; border:1px solid var(--line); border-radius:10px; + flex:none; width:38px; height:38px; padding:0; margin-left:2px; + display:inline-flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; + background:transparent; border:0; border-radius:9px; cursor:pointer; } .sw-toggle span{ - display:block; width:17px; height:2px; border-radius:2px; - background:var(--fg); transition:transform .18s ease, opacity .18s ease; + display:block; width:18px; height:2px; border-radius:2px; + background:var(--fg); } -.sw-toggle:hover{border-color:var(--brand); background:var(--brand-soft)} -.sw-toggle[aria-expanded="true"]{border-color:var(--brand); background:var(--brand-soft)} -/* 展开时变成 × */ -.sw-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)} -.sw-toggle[aria-expanded="true"] span:nth-child(2){opacity:0} -.sw-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)} +.sw-toggle:hover{background:var(--brand-soft)} +.sw-toggle[aria-expanded="true"]{background:var(--brand-soft)} -/* ---------- 软件抽屉:一律竖排浮层,覆盖在正文之上 ---------- - * 用户 2026-11-03:「都保持统一,点了之后下拉出来一个条一个条竖着排列, - * 把下面的内容全部盖住」。 - * 早期实现是宽屏横排、窄屏竖排两套,结果手机上会跟正文撞在一起; - * 现在只有一种形态:绝对定位的浮卡,overlay 盖住页面内容。 */ +/* ---------- 软件下拉菜单(右上角三横线) ---------- + * 参考家书 FamilyBook 顶栏那个 popup 的做法:**内容多高就多高的小浮窗**, + * 紧贴按钮下方、宽度由内容撑开,不是铺满整屏的面板,也不加遮罩。 + * 用户 2026-11-03:「不用做那么复杂,就是点了之后拉下来一个很窄的框, + * 把所有的内容都铺在上面就可以了」。 + * + * ⚠️ 用过两版都不对: + * ① 宽屏横排 / 窄屏竖排两套 —— 手机上和正文撞在一起 + * ② 整幅 absolute 面板 + 遮罩 —— 太重了,像侧边栏而不是下拉菜单 + * 现在只有这一种形态:小浮窗,贴按钮右侧对齐。 */ .sw-panel{ - position:absolute; left:0; right:0; top:100%; + position:absolute; top:calc(100% - 4px); right:12px; z-index:60; + min-width:172px; max-width:min(280px, calc(100vw - 24px)); + padding:6px; background:var(--card); - border-top:1px solid var(--line); - border-bottom:1px solid var(--line); - box-shadow:0 18px 40px -12px rgba(20,30,50,.28); - max-height:calc(100vh - 66px); + border:1px solid var(--line); + border-radius:12px; + box-shadow:0 10px 28px -8px rgba(20,30,50,.28), 0 2px 6px rgba(20,30,50,.08); + max-height:calc(100vh - 90px); overflow:auto; } -.sw-panel .wrap{padding-top:14px; padding-bottom:14px} -.sw-panel-hd{ - font-size:13px; font-weight:600; color:var(--muted); - margin-bottom:8px; letter-spacing:.2px; -} -/* 永远竖排:一条一行,不再有宽屏横排分支 */ -.sw-panel-list{display:flex; flex-direction:column; gap:2px} +/* 菜单里不再需要「选择软件」这个标题 —— 按钮本身已经说明用途 */ +.sw-panel-hd{display:none} +.sw-panel .wrap{padding:0; max-width:none} +/* 一条一行,竖排 */ +.sw-panel-list{display:flex; flex-direction:column; gap:1px} .sw-item{ - display:flex; align-items:center; gap:10px; - padding:10px 12px; border-radius:10px; color:var(--fg); - border:1px solid transparent; + display:flex; align-items:center; gap:8px; + padding:8px 10px; border-radius:8px; color:var(--fg); + font-size:14px; white-space:nowrap; + border:0; } -.sw-item:hover{background:var(--bg, #f6f8fb); text-decoration:none; color:var(--fg)} -.sw-item.on{background:var(--brand-soft); border-color:var(--brand-soft)} +.sw-item:hover{background:var(--brand-soft); text-decoration:none; color:var(--fg)} +.sw-item.on{background:var(--brand-soft)} .sw-item.on .sw-badge-nm{font-weight:700} +.sw-item .sw-badge{gap:7px} +.sw-item .sw-badge-nm{font-size:14px; font-weight:500} +.sw-item .sw-badge-img{width:18px !important; height:18px !important} +/* 「当前」标记缩成一个小圆点,别在窄框里占地方 */ .sw-item-cur{ - margin-left:auto; font-size:11.5px; font-weight:600; color:var(--brand); - background:var(--card); border:1px solid var(--brand); - padding:1px 8px; border-radius:99px; -} - -/* 抽屉打开时给正文加一层遮罩,点它也能关 —— 视觉上更明确「盖住了」 */ -.sw-mask{ - position:fixed; inset:0; z-index:55; - background:rgba(15,23,35,.18); + margin-left:auto; + width:6px; height:6px; flex:none; border-radius:50%; + background:var(--brand); + font-size:0; line-height:0; overflow:hidden; text-indent:-999px; } .topbar .brand-text{overflow:hidden; text-overflow:ellipsis; white-space:nowrap} .topbar .logo-mark{ diff --git a/lib/bootstrap.php b/lib/bootstrap.php index bda417b..63ebff5 100644 --- a/lib/bootstrap.php +++ b/lib/bootstrap.php @@ -8,7 +8,7 @@ if (!defined('FB_ROOT')) { define('FB_ROOT', dirname(__DIR__)); // 静态资源版本号:改 assets/ 下的 css/js 后把这个数字 +1, // 让浏览器与 CDN 缓存失效。全站只此一处,别再往页面里写死数字。 - if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 21); } + if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 28); } } /* ------------------------------------------------------------------ diff --git a/lib/layout.php b/lib/layout.php index 988c45e..33f6fef 100644 --- a/lib/layout.php +++ b/lib/layout.php @@ -88,24 +88,16 @@ function fb_layout_head($title, array $opt = []) { 我要反馈 1): ?> - + - - - 1): ?> - - -