onhashchange 只能绑定到 window 对象,不能写在 body 或其他标签上;需用 addeventlistener 或 window.onhashchange,并手动初始化路由逻辑,改 hash 应用 location.hash 而非 href。

onhashchange 不是 标签的合法属性,直接写在 HTML 标签上无效。
onhashchange 只能绑定到 window 对象
浏览器规范只允许 onhashchange 作为 window 的事件处理器存在。写成 不会触发任何逻辑,也不会报错——它只是被忽略的无效属性。
- ✅ 正确做法:用
window.addEventListener('hashchange', handler)或window.onhashchange = handler - ❌ 错误写法:
、<div onhashchange="..."> 都不起作用<li>⚠️ 注意:<code>window.onhashchange = handler容易被后续赋值覆盖,推荐用addEventListener保证多个监听器共存 - 必须在
DOMContentLoaded或window.onload中主动执行一次路由逻辑 - 取 hash 值要用
location.hash.slice(1)(例如#/about→/about),别用substr(0, 1)或漏掉空值 fallback - 示例:
function render(path) { /* 渲染逻辑 */ }<br>render(location.hash.slice(1) || '/home');<br>window.addEventListener('hashchange', () => render(location.hash.slice(1))); - ✅ 正确写法:
window.location.hash = '/about'(自动补#,不触发额外 history 记录) - ❌ 错误写法:
location.href = '#/about'、location.assign('#/about') - ⚠️ 补充:原生锚点跳转(比如
<a href="#section1"></a>)也会改location.hash并触发事件,但你可能不想把它当路由处理——得加守卫过滤非路由格式(如不含/开头的 hash)
页面首次加载时 hashchange 不触发,必须手动初始化
URL 是 https://example.com/#/user 直接打开,hashchange 事件根本不会触发——它只响应“变化”,不响应“初始状态”。结果就是白屏,点链接才动。
改 hash 时别用 location.href,否则多一条历史记录
用 document.location.href = '#/about' 会把整个 URL 当作新地址推入 history stack,用户点后退会先回到 https://example.com/# 这个无意义状态。
最容易被忽略的是:hashchange 的触发边界很窄——它只对 # 后内容变化敏感,对查询参数、路径变动完全无感;而手动初始化那一步,90% 的白屏问题都卡在这儿。











