onhashchange不能直接做路由,必须配合location.hash解析、手动触发初始化并处理空字符串边界;仅监听hashchange会漏掉首次加载,导致页面空白。

onhashchange 本身不能直接做路由——它只是个事件监听器,不处理初始加载、不管理路由表、也不自动执行匹配逻辑。必须配合 location.hash 解析和手动触发初始化,否则用户直接访问 https://site.com/#/user 时页面空白。
为什么不能只写 window.onhashchange = handler
这是最常踩的坑:页面首次加载带 hash 时,hashchange 事件根本不会触发。浏览器只在 hash「变化」时发事件,而初始加载不算变化。
- 访问
https://site.com/#/about→hashchange不触发 → 视图不渲染 - 后续点击跳转(如从
/about切到/home)→ 才触发 -
window.onhashchange是旧式写法,推荐用addEventListener,避免被覆盖
location.hash.slice(1) 取路径时漏掉空字符串处理
当 URL 是 https://site.com/# 或纯 https://site.com/ 时,location.hash 值为 "" 或 "#",.slice(1) 后得到空字符串 "",不是预期的 "/"。
- 正确做法:
const path = location.hash.slice(1) || "/" - 错误写法:
location.hash.substring(1)—— 对""会返回"",但对"#"返回空,仍需兜底 - 别忘了路由表里也要注册
"/"对应的首页回调,否则|| "/"之后查不到 handler
跳转时误用 location.href = "#/xxx"
这会导致整页刷新或跳转到新地址,破坏 SPA 体验。哈希路由必须只改 hash 部分,不碰协议/域名/路径。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确:
location.hash = "/xxx"(自动补#) - ❌ 错误:
location.href = "#/xxx"(可能触发重定向或跨域问题) - ❌ 错误:
location.assign("#/xxx")(同 href,整页跳) - 链接上也别写
<a href="#/xxx">—— 点击时浏览器会滚动到 id="xxx" 元素,优先级高于路由;应加onclick="location.hash='/xxx';return false;"或用preventDefault
真正极简的哈希路由,核心就三件事:监听 load 和 hashchange、安全取 path、严格用 location.hash = 跳转。其余都是包装——比如加路由表、支持参数、嵌套路由,都会立刻增加复杂度,而且容易在 history 栈、重复触发、异步渲染时机上出问题。



















