静态个人页面的开发(更新版)

这篇文章基于我早期那篇《静态个人页面的开发》的写作结构,但内容全部按“现在仓库的真实代码”重新整理了一遍:保留“单页 + 组件化”的思路,同时补全后来迭代出来的天气背景、一言交互、资源本地化等细节。

项目地址https://www.hxdxw.cn
技术栈:原生 HTML + CSS + JavaScript,无任何框架依赖
更新时间:2026-05-12

? 目录


目录结构

当前仓库是“可直接部署的静态产物”,根目录打开 index.html 就能运行:

www.hxdxw.cn/
├── index.html              # 主页面
├── style.css               # 全局样式(含暗色变量)
├── weather-bg.js           # 天气背景 + 播放器主题联动
├── hitokoto.js             # 一言模块(本地随机 + 复制/刷新/搜索)
├── avatar-fallback.svg     # QQ 头像加载失败兜底
├── theme.js                # 主题切换逻辑(当前未挂载按钮,属于预留)
├── CNAME                   # GitHub Pages 自定义域名
└── xf-MusicPlayer/         # 悬浮音乐播放器(本地引入)
    ├── js/
    ├── css/
    ├── icon/
    ├── images/
    └── README.md

HTML 结构

页面仍然是“单页 + 组件化”的风格:把模块按功能分块放好,整体结构一眼能读懂。

下面是当前 index.html 的核心结构(做了适当删减,只保留关键模块):

<body>
  <!-- 天气背景层(全屏固定) -->
  <div id="weather-bg" aria-hidden="true">
    <div class="weather-layer weather-gradient"></div>
    <div class="weather-layer weather-clouds"></div>
    <div class="weather-layer weather-particles"></div>
    <div class="weather-layer weather-light"></div>
  </div>

  <!-- 天气状态胶囊(左上角) -->
  <div id="weather-meta" class="weather-meta" aria-live="polite">正在同步天气...</div>
  <script src="weather-bg.js"></script>

  <!-- 头像卡片 -->
  <section class="profile-wrap" aria-label="个人资料">
    <div class="avatar-wrap">
      <div class="bubble" aria-hidden="true">Hello World!</div>
      <img class="avatar"
           src="https://q1.qlogo.cn/g?b=qq&nk=915678975&s=640"
           onerror="this.onerror=null;this.src='avatar-fallback.svg';"
           alt="火芯Ah 的头像" />
    </div>
    <div class="profile-info">
      <p class="profile-name">火芯Ah</p>
      <p class="profile-desc">rm -rf ./个人描述</p>
    </div>
  </section>

  <!-- 一言 -->
  <div class="hitokoto-wrap" id="hitokoto-wrap">
    <span id="hitokoto-text">加载中...</span>
    <button class="action-btn" id="copy-btn" title="复制">...</button>
    <button class="action-btn" id="refresh-btn" title="换一句">...</button>
    <button class="action-btn" id="search-btn" title="搜索">...</button>
  </div>
  <script src="hitokoto.js"></script>

  <!-- 导航按钮 -->
  <nav class="nav-buttons" aria-label="站点导航">
    <a class="nav-btn" href="https://blog.hxdxw.cn" target="_blank" rel="noopener noreferrer">
      <span>火芯の博客</span>
    </a>
    <a class="nav-btn" href="https://blog.hxdxw.cn/index.php/18.html" target="_blank" rel="noopener noreferrer">
      <span>火芯の在线工具</span>
    </a>
  </nav>

  <!-- 音乐播放器 -->
  <div id="xf-MusicPlayer"
       data-fadeOutAutoplay
       data-themeColor="xf-wineRed"
       data-randomSongList="1"></div>
  <script src="./xf-MusicPlayer/js/xf-MusicPlayer.min.js"></script>
</body>

设计要点

  • “氛围层”与“内容层”分离:天气背景固定在最底层,内容永远清晰可读
  • aria-live="polite":天气状态更新时,对无障碍阅读器更友好
  • 头像 onerror:外链头像失效时,用本地 SVG 兜底,避免页面破相

CSS 架构

1. CSS 变量系统

CSS 依然以变量为核心:一组变量控制全局配色、阴影、动效曲线;暗色主题通过 [data-theme="dark"] 覆盖变量实现。

(下面为简化示例)

:root {
  --bg: #f5f5f7;
  --card-bg: #ffffff;
  --text-primary: #1d1d1f;
  --text-secondary: #6e6e73;
  --accent: #0071e3;
  --shadow-sm: 0 2px 8px rgba(0,0,0,.08);
  --shadow-md: 0 8px 32px rgba(0,0,0,.12);
  --transition: .3s cubic-bezier(.4,0,.2,1);

  /* 天气相关变量(云层透明度可动态改) */
  --weather-sky-top: #73b6ff;
  --weather-sky-bottom: #d7efff;
  --weather-cloud-opacity: .32;
}

[data-theme="dark"] {
  --bg: #292929;
  --card-bg: #393939;
  --text-primary: #f5f5f5;
  --text-secondary: #b0b0b0;
  --accent: #0a84ff;
  --shadow-sm: 0 2px 8px rgba(0,0,0,.28);
  --shadow-md: 0 8px 32px rgba(0,0,0,.35);
}

2. 头像卡片组件

头像卡片的“气泡 + 悬停动画”是这页最经典的交互点。实现上是纯 CSS:默认隐藏气泡,悬停时做透明度和缩放过渡。

.avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--shadow-md);
  transition: transform var(--transition), box-shadow var(--transition);
}

.bubble {
  opacity: 0;
  transform: scale(.7) translateY(4px);
  transition: opacity var(--transition), transform var(--transition);
}

.profile-wrap:hover .bubble {
  opacity: 1;
  transform: scale(1) translateY(0);
}

3. 导航按钮

按钮保持“轻拟物”的质感:边框 + 阴影 + 轻微抬升;不做过重的玻璃拟态,保证浅色/深色都不刺眼。


4. 天气背景层

天气背景的核心是两点:

  1. 天空渐变通过 --weather-sky-top/bottom 控制
  2. 云层透明度通过 --weather-cloud-opacity 控制(会跟随实时云量变化)

这使得“天气变化”更多是氛围变化,而不是突兀地换一张图。


5. 一言模块

一言区域是固定在底部的一个小条,交互按钮尽量做小、做轻:不抢主视觉,但需要时能随手用。


JavaScript 功能

1. 天气同步逻辑

对应 weather-bg.js,整体链路如下:

  1. 尝试使用浏览器定位获取经纬度
  2. 请求 open-meteo 的天气接口拿到当前天气(天气码/昼夜/云量/温度)
  3. 把天气码归类成 晴/多云/阴/雾/雨/雪/雷雨
  4. 写入页面状态(data-weather / data-daypart)并动态调整云层透明度
  5. 每 15 分钟刷新一次

容错策略

纯静态站点最怕依赖不稳定,所以这里做了两层兜底:

  1. 定位失败:回退到固定位置(北京),并在左上角状态提示原因
  2. 天气接口失败:回退到“默认晴天背景”

2. 一言交互逻辑

对应 hitokoto.js

  1. 本地数组随机一条文案
  2. 复制按钮优先使用 navigator.clipboard,失败降级为选中内容
  3. 刷新按钮重新随机
  4. 搜索按钮跳转到搜索引擎查询当前文案

3. 主题切换(预留)

仓库里有 theme.js(逻辑完整,支持系统偏好 + 本地存储),但当前 index.html 还没有挂载切换按钮与脚本,所以这部分属于“预留功能”。

如果后续要启用,最小改动一般是:

  1. 在页面加一个 #theme-toggle 按钮(以及 #theme-icon
  2. 引入 theme.js

音乐播放器组件

播放器使用 xf-MusicPlayer,采用本地引入(仓库自带 xf-MusicPlayer/),减少外链不稳定风险。

当前页面初始化方式:

<div id="xf-MusicPlayer"
     data-fadeOutAutoplay
     data-themeColor="xf-wineRed"
     data-randomSongList="1"></div>
<script src="./xf-MusicPlayer/js/xf-MusicPlayer.min.js"></script>

另外我在 weather-bg.js 里做了一个小联动:根据天气场景动态切换播放器主题色,让整体氛围更一致。


文件结构

从“部署”的角度看,这个仓库就是典型的静态站点发布形态:根目录即产物、无需构建、资源尽量本地化。


技术总结

技术点应用场景
CSS Custom Properties全局主题与配色系统
[data-theme="dark"] 覆盖变量暗色主题(当前预留未挂载)
transform + transition头像悬停动画、按钮抬升
浏览器定位 API获取当前位置天气
open-meteo 天气接口天气码/云量/温度数据
navigator.clipboard一言复制(失败降级)
data-* 属性音乐播放器配置化

个人页面预览www.hxdxw.cn
个人页面 GitHub 仓库shihuoxin/hxdxw.github.io
xf-MusicPlayer作者github仓库:https://github.com/cenguigui/xf-MusicPlayer-master

评论区:

还没有评论,快来抢沙发吧!