feat(关于页): 重设计为「时间线 + 数据一览」版式,动效对齐全站 UIKit 范式

- 版式:01 关于我(属性四行 + 时间线四节点 + 三张数据卡 + 分类 Top5 条,
  全部构建期实时统计,新增 partial about-intro.html)+ 02 这个博客 + 03 走心
  评论 + 04 热力图,间距统一由 .about-sec 管,字号统一四档
- 动效:纯官方 UIKit scrollspy(与归档页同源)—— target 一律后代选择器、
  动画类用 uk-animation-slide-*-medium(50px 位移)+ repeat:true 滚回重播、
  分节标题 fade 不 repeat;删自研编排器,CSS 只留分类条宽度填充与
  prefers-reduced-motion 守卫
- 修复 PJAX 下 UIKit 不重绑的既有 bug:mypjax.js 换页后调 UIkit.update()
  (评论区/说说的 scrollspy 同样依赖此修复)
- 走心评论:骨架屏、8s 超时、sessionStorage 缓存(10 分钟)、重试按钮;
  异步渲染后手动 UIkit.update() 让卡片参与入场级联
This commit is contained in:
zqlit committed 2026-10-07 21:45:46 +08:00
1 parent a884180787
commit 654de1fdf0
7 files changed
+692 -88

No files matched your search

+78 -48
View File
@@ -1,57 +1,87 @@
{{ define "main" }}
<div id="pjax-container" data-needs-echarts="true">
<div class="post-content" itemprop="articleBody" uk-scrollspy="target: > *; cls: uk-animation-slide-bottom-small; delay: 100">
{{ .Content }}
{{ $sectionCount := 0 }}
{{/* 关于页分节顺序:01 关于我(partial,含属性+时间线+数据)
02 这个博客(content/about.md)
03+ 走心评论 / 热力图 / 技能栈 / 相册,按 hugo.toml 开关动态编号。
间距统一由 .about-sec 管,别写内联 margin。
<!-- Featured Comments Section(走心评论:管理员精选的评论,数据来自 Worker) -->
{{ if site.Params.about.enablefeatured | default true }}
{{ $sectionCount = add $sectionCount 1 }}
<div style="margin-top: 40px;">
<div class="section-title">{{ printf "%02d" $sectionCount }} / 走心评论 (Featured)</div>
{{ partial "featured-comments.html" . }}
</div>
{{ end }}
── 动效:与归档页 archives.html 完全同源的官方写法(v7,零自定义 JS)──
官方文档(uikit.cn/docs/animation):
「将 .uk-animation-* 类之一添加到任何元素。当添加类时会显示动画…要在
其他时间点显示动画,例如当元素进入视口时,您需要使用 JavaScript
添加该类 —— 例如,使用滚动监听组件。」
<!-- Heatmap Section -->
{{ if site.Params.about.enableheatmap }}
{{ $sectionCount = add $sectionCount 1 }}
<div style="margin-top: 40px;">
<div class="section-title">{{ printf "%02d" $sectionCount }} / 热力图 (Hot Map)</div>
{{ partial "heatmap.html" . }}
</div>
{{ end }}
四条要点(全部页面既有范式,本页照办):
① scrollspy 挂在被包裹的容器上,一个容器托管一组元素。
② target 用后代选择器(.ab-attr),不写 `>` —— 写 `>` 只匹配直接
子元素,结构一变就一个都选不中(v4 动画全灭的根因)。
③ 动画类一律官方:uk-animation-fade(标题淡入 0.8s)、
uk-animation-slide-{bottom,right}-medium(内容 50px 滑入 0.5s)。
★ 不要用 -small:位移只有 10px,在这么宽的版面里根本看不出来。
④ 内容组一律 repeat: true —— 移出视口重藏、滚回重播(归档页年份
标题同款),页面滚动时才是「活的」;分节标题不 repeat(同归档 h3)。
<!-- Skills Section -->
{{ if site.Params.about.enableskills }}
{{ $sectionCount = add $sectionCount 1 }}
<div style="margin-top: 40px;">
<div class="section-title">{{ printf "%02d" $sectionCount }} / 技能栈 (System Ops)</div>
{{ partial "skills.html" . }}
</div>
{{ end }}
<!-- Album Section -->
{{ if site.Params.about.enablealbum }}
{{ $sectionCount = add $sectionCount 1 }}
<div style="margin-top: 40px;">
<div class="section-title">{{ printf "%02d" $sectionCount }} / 光影 (Album)</div>
<div class="album-content" uk-scrollspy="target: > .album-item; cls: uk-animation-slide-bottom-small; delay: 100">
{{ range site.Data.album }}
<div class="album-item">
<div class="album-img-box">
<img src="{{ .image }}" loading="lazy">
{{ if .date }}<span class="album-date-badge">{{ .date }}</span>{{ end }}
<div class="album-info">
<span class="album-title">{{ .title }}</span>
PJAX:换入的 DOM 由 mypjax.js 的 reinitUIKit() 重新 boot(UIKit 的
MutationObserver 只反应属性新增,管不了 PJAX 整树换入)。
异步渲染的内容(走心评论卡片)渲染完要自己调 UIkit.update()。 */}}
<div id="pjax-container" data-needs-echarts="true">
<div class="post-content about-page" itemprop="articleBody">
<div class="about-sec">
<div class="section-title" uk-scrollspy="cls: uk-animation-fade; delay: 100">01 / 关于我 (Timeline)</div>
{{ partial "about-intro.html" . }}
</div>
{{ .Content }}
{{ $sectionCount := 2 }}
<!-- Featured Comments Section(走心评论:管理员精选的评论,数据来自 Worker) -->
{{ if site.Params.about.enablefeatured | default true }}
{{ $sectionCount = add $sectionCount 1 }}
<div class="about-sec">
<div class="section-title" uk-scrollspy="cls: uk-animation-fade; delay: 100">{{ printf "%02d" $sectionCount }} / 走心评论 (Featured)</div>
{{ partial "featured-comments.html" . }}
</div>
{{ end }}
<!-- Heatmap Section -->
{{ if site.Params.about.enableheatmap }}
{{ $sectionCount = add $sectionCount 1 }}
<div class="about-sec">
<div class="section-title" uk-scrollspy="cls: uk-animation-fade; delay: 100">{{ printf "%02d" $sectionCount }} / 热力图 (Hot Map)</div>
{{ partial "heatmap.html" . }}
</div>
{{ end }}
<!-- Skills Section -->
{{ if site.Params.about.enableskills }}
{{ $sectionCount = add $sectionCount 1 }}
<div class="about-sec">
<div class="section-title" uk-scrollspy="cls: uk-animation-fade; delay: 100">{{ printf "%02d" $sectionCount }} / 技能栈 (System Ops)</div>
{{ partial "skills.html" . }}
</div>
{{ end }}
<!-- Album Section -->
{{ if site.Params.about.enablealbum }}
{{ $sectionCount = add $sectionCount 1 }}
<div class="about-sec">
<div class="section-title" uk-scrollspy="cls: uk-animation-fade; delay: 100">{{ printf "%02d" $sectionCount }} / 光影 (Album)</div>
<div class="album-content" uk-scrollspy="target: .album-item; cls: uk-animation-slide-bottom-medium; delay: 100; repeat: true">
{{ range site.Data.album }}
<div class="album-item">
<div class="album-img-box">
<img src="{{ .image }}" loading="lazy">
{{ if .date }}<span class="album-date-badge">{{ .date }}</span>{{ end }}
<div class="album-info">
<span class="album-title">{{ .title }}</span>
</div>
</div>
</div>
{{ end }}
</div>
{{ end }}
</div>
{{ end }}
</div>
</div>
{{ end }}
</div>
</div>
{{ end }}
{{ end }}