hashchange事件是spa路由核心机制,需用addeventlistener监听并手动触发首次路由;匹配时应截取location.hash的路径部分再比对,避免直接===;跳转统一用location.hash赋值,禁用pushstate;dom更新需手动管理并重绑事件。

hashchange 事件监听是核心机制
浏览器地址栏中 # 后面的部分(即 hash)变化时,不会触发页面刷新,但会触发 window 的 hashchange 事件——这是实现 SPA 路由最轻量、兼容性最好的基础。
注意:不能只靠 location.hash 初始化读取一次就完事,必须监听该事件才能响应用户点击后退/前进、手动改地址栏等行为。
- 监听写法必须用
window.addEventListener('hashchange', handler),不要用onhashchange属性,避免被覆盖 - 首次加载时
hashchange不会触发,需手动调用一次路由处理函数,比如router() - IE8+ 支持
hashchange,但 IE7 及更早版本不支持(如需兼容,得降级为定时轮询location.hash,不推荐)
路由匹配要用正则或精确字符串比对
location.hash 返回的是带 # 的完整字符串(如 #/user/123),直接 === 匹配容易出错。常见错误是忽略开头的 # 或没处理末尾斜杠。
推荐做法:统一提取路径部分再比对,例如:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
const path = location.hash.slice(1) || '/'; // 得到 '/user/123' 或 '/'
- 简单场景可用
switch(path)或对象映射:routes[path] && routes[path]() - 需要参数解析(如
#/post/42中的42)建议用正则:path.match(/^\/post\/(\d+)$/) - 避免用
indexOf模糊匹配,否则/user会误中/user-profile
pushState 不适合纯 hash 路由场景
有人看到 SPA 就下意识想用 history.pushState,但它操作的是 URL 路径(/user),和 hash 路由(#/user)属于两套机制。混用会导致行为不一致甚至路由丢失。
- 如果坚持用 hash,就别碰
pushState和replaceState,所有跳转用location.hash = '#/xxx' -
location.hash = ''会清空 hash 并跳到页面顶部,要避免意外滚动,可加location.hash = '#'代替 - 动态修改 hash 时,
hashchange仍会触发,无需额外 dispatch
组件切换要手动管理 DOM 或状态
没有框架时,路由只是决定“显示哪块 HTML”,你得自己控制 DOM 显示隐藏、或替换内容区域。常见错误是反复 innerHTML 导致事件绑定丢失、资源未清理。
- 推荐预先定义好视图容器(如
<main id="app"></main>),每次路由匹配后只更新其innerHTML或textContent - 若视图含交互逻辑(如按钮点击),应在每次渲染后重新绑定事件,或用事件委托(绑定在
#app上,监听子元素) - 不要在路由函数里直接操作全局变量模拟“状态”,容易和异步操作冲突;简单应用可用闭包封装当前视图状态
hash 路由看似简单,但 history 状态管理、嵌套路由、路由守卫这些高级能力都得自己补全——一旦业务变复杂,很快就会发现缺个真正的路由库不是少几行代码的事。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










