太好了,我们就用你上传的代码,把“从‘看网页’到‘做网页’”这篇文章(slug=post-2025-08-31-kekgcy)从首页 → 文章详情页的完整“路由流程”走一遍,并把关键代码逐行标注出来。你现在的首页是 SPA(单页应用) 风格的哈希路由:URL 形如 index.html#/post/<slug>,页面不刷新,只切换视图。


1) 首页里“文章卡片/表格链接” → 改写 URL 的 hash

当首页渲染文章列表时,会给每篇文章生成一个指向哈希路由的链接:

<!-- script.js 第120–136行附近(生成卡片) -->
<a href="#/post/${a.slug}" class="stretched-link">阅读全文</a>  <!-- 关键:点击只改变 hash -->

<!-- script.js 第147–153行附近(生成表格行) -->
<td><a href="#/post/${a.slug}">${titleCell}</a></td>          <!-- 同样是 hash 链接 -->

作用:当你点击“从‘看网页’到‘做网页’”时,浏览器地址会变成 …/index.html#/post/post-2025-08-31-kekgcy,页面不刷新,只是 hash 改变。


2) 监听 hash 变化 → 进入自定义 router

页面启动时注册了路由器,并监听 hashchange:

// script.js 第330–332行
window.addEventListener("hashchange", router);
router(); // 首次进入页面时也跑一次

作用:无论是首次打开,还是点击文章导致 hash 变化,都会进入 router() 决定显示哪个视图。


3) 解析 hash → 判定要显示“文章详情/联系/演示/列表”

// script.js 第280–287行
function parseHash() {
  const hash = location.hash || "#/";
  const m = hash.match(/^#\\/post\\/([\\w-]+)$/);
  if (m) return { view: "post", slug: m[1] };   // 命中文章详情,提取 slug
  if (hash.startsWith("#/contact")) return { view: "contact" };
  if (hash.startsWith("#/demo"))    return { view: "demo" };
  return { view: "list" };                            // 默认列表页
}

作用:当 hash 是 #/post/post-2025-08-31-kekgcy 时,解析结果为 { view: "post", slug: "post-2025-08-31-kekgcy" }。


4) 路由分发:根据 view 调用不同渲染函数

// script.js 第314–321行
async function router() {
  const { view, slug } = parseHash();
  switch (view) {
    case "post":    await showDetailBySlug(slug); break;  // 进入文章详情
    case "contact": toContact();               break;
    case "demo":    toDemo();                  break;
    default:        await renderList(); toList();
  }
}