KAIROS.WORKSPACE
技术宇宙 / ONLINE
返回踩坑地图
前端工程中级4 分钟

window.location.href 悄悄旁路了你的客户端路由

在启用 View Transitions/SPA 路由的站点里,命令面板与终端用 window.location.href 跳转会强制整页刷新,丢失过渡与内存态的复盘与锚点点击修复法。

#Astro#View Transitions#导航#调试

现象

命令面板(Ctrl/Cmd+K)、彩蛋终端的 open <section>、首页可交互终端——这些“输入即跳转”的交互,视觉上工作正常,但体验上有一处不对劲:点击跳转时页面整页重载。表现是 View Transitions 的淡入淡出动画没有出现,某些存在内存里的临时状态(比如本会话已展开的面板)被清空。

根因

这些跳转统一用了:

window.location.href = target;

在 Astro <ClientRouter>(或任何 History-API 驱动的 SPA 路由)里,路由拦截器监听的是 click 事件与 popstate,而不是 location.href 的赋值。直接改 location.href 属于“编程式整页导航”,浏览器会老老实实卸载当前文档、重新请求目标——路由的增量渲染层根本没机会介入。于是 SPA 退化成 MPA。

修复:合成锚点点击

让跳转“看起来像用户点了链接”,路由拦截器自然接管:

const navigateTo = (href) => {
  if (!href) return;
  const link = document.createElement('a');
  link.href = href;
  document.body.append(link);
  link.click();
  link.remove();
};

点击一个同域 <a> 会触发路由的 astro:link-click/拦截逻辑,走增量换页;而如果路由不可用(首屏未水合、浏览器不支持),这次点击自动降级为普通导航,不会比 location.href 更差。零额外依赖。

对需要绝对 URL 的场景(如接口返回的 statusUrl)同样适用,浏览器会解析 link.href

何时仍该用 location.href

不是所有跳转都要 SPA 化。这些情况故意整页刷新更合理:

  • 跳转到站外/不同子域(本就该脱离路由);
  • 强制重载以拉取新构建产物(发布预览);
  • 登录/登出后需要清空所有内存态。

区分标准是“目标是否在同一应用壳内”。站内常规导航交给路由,跨边界或需要重置的场景保留 location.href

验证

一个便宜的回归断言:跳转前在页面 window.__spaMarker = 1,跳转后读回——若仍是 1 说明文档没被卸载,走了 SPA 路径;若变 undefined 说明整页刷新了。本项目命令面板与终端跳转的回归测试就用了这个标记法。