把动态页改成了朋友圈的样子

2159 字
11 分钟
把动态页改成了朋友圈的样子
把动态页改成了朋友圈的样子

动态页想换个样子。参照的是另一个同主题的站,数据源不变 —— 还是继续接 memos,只换皮。

改完的动态页:封面区、卡片、评论区一起换了
改完的动态页:封面区、卡片、评论区一起换了

动手前先扒两边#

参考站也是 Firefly 的 fork,但它那套动态是自己写的组件(MomentCard.astro 加一个独立页面)。按这个路子走,得新开一个页面、把数据管线重接一遍 —— 动静不小。

所以先把我们的动态页 DOM dump 出来看了一眼:

dynamic-entry.page-entry.card-base > article
├ page-entry-header → page-avatar / page-identity(page-author + page-meta)
│ / page-pinned-badge / page-entry-decoration
├ page-content
├ dynamic-gallery → page-gallery-grid
└ dynamic-inline-comments → page-comment-toggle + page-comment-panel

头像、作者、时间、地点、置顶徽章、图片网格、评论按钮 —— 一个不缺。参考站那套 card-header / card-avatar / card-tags 跟它几乎是逐项对应的。

差的只是样式。那就不用新开页面了:纯样式覆盖,加一点脚本补它没有的东西。

约束还是老一套:src/pages/、src/components/、src/styles/ 这些红线一根不碰。做法是——

文件状态干什么
public/assets/css/dynamic-card.css新增全部样式,只在 /dynamic/ 加载
public/assets/js/dynamic-hero.js新增把页脚的封面区外壳搬进正文
src/config/FooterConfig.html改(追加)封面区外壳与文案、PAGE_STYLES 条目

卡片:先从竖条开始#

参考站卡片最显眼的是左边一根主题色竖条。上游的 .page-entry 是 overflow: visible,竖条贴边会被裁掉,所以先把它裁住:

dynamic-entry.page-entry {
position: relative;
overflow: hidden;
padding: 1rem;
}
dynamic-entry.page-entry::before {
position: absolute;
inset: 0 auto 0 0;
width: 4px;
border-radius: 0 2px 2px 0;
background: var(--primary);
opacity: 0.35;
content: "";
}

其余都是对着参考站抄:头像从 48px 收到 40px 并加一圈 2px 主题色描边、昵称改成主题色、时间与地点之间补一个 ·(上游只靠 gap 分隔)、正文取消那个跟头像对齐的 3.75rem 缩进、右上角那枚纯装饰的引号撤掉。

所有选择器都挂 dynamic-entry 前缀。上游的 .page-* 在友链页、书签导航那批自建页里也在用,不加前缀会误伤一片。

图片网格踩到特异性#

参考站的网格是固定 100px 的方块(按张数排 1 / 2 / 3 列)。我们上游本来是自适应宽度,所以要把尺寸压成固定的:

dynamic-entry .page-gallery > .page-gallery-grid {
width: fit-content;
grid-auto-rows: 100px;
grid-template-columns: repeat(3, 100px);
}

写完一测——格子还是被摊开。原因在特异性:

选择器特异性
上游 .page-gallery-grid[data-count="2"](还写着 width: min(100%, 28rem))0-2-0
我写的 dynamic-entry .page-gallery-grid0-1-1

0-2-0 赢。 容器宽度始终是 448px(=28rem),格子设成 100px 也只是被这 448px 平分。改成 dynamic-entry .page-gallery > .page-gallery-grid[data-count=…](0-3-1)才拿下。

最终实测:单图 100px、2 图 206、3 图 312、4 图 206(两列)、6 与 9 图 312(三列)—— 跟参考站的规则对上了。窄屏(≤480px)转自适应均分。

单图我保留了上游的「完整显示不裁剪」,没照搬成 100px 方块。一张风景照被裁成小方块,实在难看。

封面区:上游没有的东西#

参考站顶部那一整块——封面大图、右下角浮出的头像、压在封面上的昵称、右对齐的签名,下面一排按钮——上游完全没有。

补它的路子是「页脚注入外壳 + 脚本搬运」:DOM 连同全部文案、链接先写在页脚的 FooterConfig.html 里,由 dynamic-hero.js 在动态页把它搬进正文顶部。

搬的时候有个要点:用 cloneNode,原壳留在页脚。因为正文整个在 swup 的替换范围里,直接把节点搬过去,切一次页就没了;原壳留着,下次切回来再克隆一份。

防重复插入,安静地失效#

页面重进会触发好几个事件(astro:page-load、swup:page:view、swup:content:replace),每个都会跑一次搬运。所以插之前得先认门。

第一版我写的是:

if (host.querySelector(":scope > .ff-wx-cover")) return;

看着挺对。实测:连触发三次事件,插出了三份封面。

换成锚点上的标记才拦住:

if (anchor.dataset.ffHeroMounted === "1") return;
anchor.dataset.ffHeroMounted = "1";

swup 换页时 .page-header 是新元素、没有标记,会重新插一份;同一份 DOM 反复触发则不会再插。实测三连触发后仍然是「页脚壳子 1 份 + 正文副本 1 份」。

封面图:每次进来随机一张#

想要的效果是:跟壁纸用同一批图,但不轮播,每次进来随机一张。

壁纸池在 backgroundWallpaper.ts 的 desktop 数组里 —— 但那是 src/assets/ 下的图,构建后路径是哈希化的 /_astro/xxx.webp,静态 HTML 里写不出来。

仓库里那张图其实有三份,用途完全不同:

位置内容能不能当封面
src/assets/images/DesktopWallpaper/壁纸本体,优化过的 webp(160–290KB)路径写不出来
public/gallery/desktop-wallpaper/相册原图(1.4–2.4MB)太重
public/images/desktop-wallpaper/复制来的轻量副本✅ 用这个

池子写在注入 HTML 的 data-covers 上(逗号分隔),脚本在挂载时随机挑一张 —— 只在挂载时挑,页面内不轮播;切进切出算一次「进来」,会重新挑。

顺带剔了一张:壁纸数组里的 cover.webp 其实是「暂无封面」那张占位图,第一版收进了池子,随机到它非常难看。

页面头部:拆掉那层壳#

封面区下面紧跟着上游的页面头部(图标 + 「站长动态」+ 描述 + RSS + 计数 + 搜索 + 年份筛选)。它自己是一张卡片,叠在封面卡片下面就是两层壳。

功能全留,壳拆了:背景、边框、圆角、阴影全撤,那个大图标也隐藏,两块的间距收到 4px —— 视觉上变成封面卡片的下半截。

「写说说」按钮本来在封面区下面单独占一行,只有一个按钮,又空又白吃一行高度。挪进了标题行右侧,跟「订阅RSS」「17 动态」排成一排(那格本来就是页面级操作区),尺寸收小到跟旁边两个小字协调。

评论区:三个小改动#

① 按钮上标评论数。 之前只有「评论」两个字,不点开不知道有没有人聊过。做法是进页面时批量问一次 Waline 的计数接口:

GET /api/comment?type=count&url=/dynamic/xxx/&url=/dynamic/yyy/…
→ {"data":[2,0,5,…]}

一次请求拿回全部,按传入顺序返回 ✓。有评论就显示「评论 2」,0 条不带数字 —— 有数字本身就是在说有人聊过。

② 只自动展开真有评论的。 一版之前做过「全部自动展开」,自己回看一遍又推翻了 —— 那时一进页面每条动态下面都摊着评论区,而其中大部分是空的。现在只展开 count > 0 的,空面板保持收起;懒展开照旧走 IntersectionObserver(离视口 400px 才展开),一页十几条全展开会把首屏拖垮。自动展开只做一次,用户手动收起后不会再被弹开。

③ 编辑器压成一行。 展开之后,Waline 那个「昵称 / 邮箱 / 网址 + 大输入框 + 表情栏」顶在最上面太挡视野。现在默认收成一个 35px 的输入框(整块 77px),点进去自动还原成完整表单(227px):

editor.classList.add("ff-compact"); // 默认压缩
editor.addEventListener("focusin", () => editor.classList.remove("ff-compact"));

用「加类 / 摘类」而不是 :not(:focus-within) 反转,是因为后者得去猜 Waline 原本的 display 到底是 flex 还是 block —— 摘类让规则干脆不生效,它自己什么样就什么样。

输入框的类名不是猜的那个#

第一版我按 .wl-textarea 写选择器,压缩样式一声不响地没生效:编辑器该多高还多高。

dump 出来才知道,Waline v3 的输入框是:

<div class="wl-comment">
<div class="wl-panel">
<div class="wl-header item3">…昵称 / 邮箱 / 网址…</div>
<textarea class="wl-editor"> ← 是它
<div class="wl-preview">…
<div class="wl-footer">…表情 / 字数 / 提交…

.wl-textarea 压根不存在。改成 .wl-editor 才对。

评论区:编辑器收成一行、按钮带评论数、回复引用照常
评论区:编辑器收成一行、按钮带评论数、回复引用照常

顺带还藏掉了「评论区 / 分享你的想法,与大家交流讨论」那行标题 —— 动态页一条动态配一个评论区,标题只是白占地方。那块来自全站共用的 src/components/comment/index.astro(上游文件),文章页里它是正文与评论的分界、有用,所以只在动态这个 iframe 里藏,没全站删。

写在最后#

这一轮从头到尾没改一个主题源文件。红线自检(src/pages、src/components、src/styles 等目录)始终是空的。

三个坑有个共同点:都不报错。特异性不够只是样式被压过去、:scope 选择器不生效、类名写错只是匹配不到 —— 没有一个会给你红字提示。所以这类改造真正花时间的不是写样式,是验证「它到底有没有生效」:算一遍特异性、dump 真实 DOM 看类名、给每个改动配一条实测。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
把动态页改成了朋友圈的样子
https://www.9ll.uk/posts/blog/dynamicpageredesign/
作者
HY
发布于
2026-10-16
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
首页加了一条会滚的动态:参考楠枝小筑,一个主题文件都没改
博客在楠枝小筑首页看到一条会一直横滚的「瞬间」条,想在自己站上也挂一个。他用的是 Ethereal 主题,代码没法照抄,所以只搬机制:Memos 数据在客户端拉,滚动靠 CSS 把轨道复制成两份,DOM 走页脚注入再加一点点搬运。最后改动落在两个文件里,主题源码一个没碰。
2
留言板改成聊天窗口:只改了主题一个文件,还少下载 82 KB
博客在 blog.amamo.top 的留言板看到群聊风格的界面:气泡、成员列表、公告栏,像开在博客里的群。扒了仓库发现后端就是 Waline,我现成有一个。约束照旧是不能动主题源文件,于是把 11 个文件搬过来之后,把原本要改 6 类上游文件的移植压到只动 guestbook.astro 一个文件,顺带把这一页的评论脚本从 100 KB 减到 23 KB。
3
给博客装了个朋友圈:把友链的更新聚成一条时间线
博客羡慕 rainzt.cn 的朋友圈,把它搬进自己的 Firefly:构建时抓取所有友链的 RSS 合流成时间线,快照兜底,GitHub Actions 每天自动刷新。纯静态,不用服务器,只新增文件不碰主题源码。后来又给时间线加了层来源配额,不让聚合站霸榜。
4
评论区回复默认展开 2 条,长串收在「展开更多」后面
博客友链页有条评论下面挂了 13 条回复,往下翻要滑过整屏;可全收起来又太狠,访客第一眼什么都看不到。最后定成默认展示 2 条,多出来的才收着,还有剩就给个「展开更多」,摊完能收回去。做法照旧只加文件不动上游。踩坑集中在一点上:Waline 是 Vue 渲染的,DOM 会重绘、会随 swup 换页被整体替换,所以折叠状态不能只靠一次性的 DOM 操作。
5
回复带上引用:别再让读者猜「@昵称」在回哪一句
博客Waline 的二级回复只渲染一行「@昵称:」,谁在回谁很清楚,回的是哪一句全靠猜。翻 DOM 发现它其实留了线索 —— 回复里那个 @昵称 的链接 href 就是被回复评论的 objectId。顺着锚点把目标评论捞回来,摘成引用块插在下面,点它还能滚过去高亮。踩了个坑:剥 @ 前缀时忘了 clone,把页面上那行整个删了。
随机文章随机推荐

评论区

Profile Image of the Author
HY
Hello, I'm HY.
公告
迷茫.... 为了访问速度,本站将会在11月上旬至中旬迁移到0dm.cn并完成备案
分类
标签
最新动态
站点统计
文章
74
分类
8
标签
192
总字数
161,979
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Vercel
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录