不能只用window.onhashchange属性,因其为单值可覆盖、不触发首次加载、ie7不支持;必须用addeventlistener监听,并手动初始化、统一slice(1)提取路径、正确跳转和dom更新。

onhashchange 本身不能直接实现可靠路由——它只是个事件入口,必须配合手动初始化、路径提取和 DOM 更新才能跑起来。光写 window.onhashchange = handler 会丢掉首次加载和 IE 兼容性,实际项目中基本不用。
为什么不能只用 window.onhashchange
这个属性是可被覆盖的:后面任何代码执行 window.onhashchange = anotherHandler,前面的监听就失效了。浏览器原生支持的是事件监听器机制,不是属性赋值。
-
window.onhashchange是单值属性,只能存一个函数;addEventListener('hashchange', ...)可叠加多个监听器 - 页面首次加载时(比如用户直接访问
https://site.com/#/user),hashchange事件根本不会触发,得靠你主动调一次处理逻辑 - IE8+ 支持
addEventListener,但 IE7 及更早版本不支持——如果真要兼容,得降级轮询,而onhashchange属性在 IE7 根本不存在,会静默失败
location.hash 怎么取才安全
很多人直接写 if (location.hash === '#/about'),结果匹配失败。因为 location.hash 返回的是带 # 的完整字符串,比如 "#/about" 或 ""(空字符串,不是 "#/")。
- 正确做法是统一用
location.hash.slice(1)提取路径部分,得到"/about"或"" - 空值要兜底:
const path = location.hash.slice(1) || '/',否则""会导致routes[""]查不到 - 别用
indexOf模糊匹配,比如location.hash.indexOf('/user') > -1——/user-profile也会命中
跳转和 DOM 更新怎么写才不出错
点击链接或 JS 跳转后,视图没更新、事件丢失、页面滚到顶部……这些都不是 bug,是没管好副作用。
- 跳转统一用
location.hash = '#/xxx',不要混用pushState;location.hash = ''会清 hash 并滚动到页首,想清空应写location.hash = '#' - DOM 更新建议用 class 切换而非反复
innerHTML:document.getElementById('app').className = 'view-' + path,再配 CSS.view-/ { display: block; } - 如果用了
innerHTML,且新内容含按钮等交互元素,必须在每次渲染后重新绑定事件,或改用事件委托(比如把 click 监听绑在#app上,用e.target.matches('[data-action]')判断)
容易被忽略的同步细节
URL 和视图状态不同步,是 hash 路由最隐蔽的问题。比如从 #/post/123 切到 #/list,再点浏览器后退,你得能还原出 123 并重新渲染详情页——这意味着解析逻辑不能只写在初始化里。
必须把路径提取、参数解析(如 /post/(\d+))、路由分发封装成独立函数,每次 hashchange 触发都走一遍,而不是只在页面加载时跑一次。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











