页面首次打开白屏是因hashchange事件不触发初始hash,需在domcontentloaded中手动执行路由初始化;改hash应使用window.location.hash赋值以避免多余历史记录,且路由hash须统一以/开头并加守卫过滤非路由锚点。

为什么页面一打开是白屏,但点链接就正常?
因为 hashchange 事件只在 hash “变化时”触发,不是“存在时”触发。URL 是 https://example.com/#/user 这种带 hash 的地址直接打开,hashchange 根本不响——浏览器认为没有“变化”,只是初始状态。
必须手动补一手初始化逻辑:
- 在
DOMContentLoaded或window.onload里立即执行一次路由函数 - 用
location.hash.slice(1)取值(比如#/about→/about),别用substr(0, 1)或漏掉|| '/'默认值 - 不要写成
window.onhashchange(),它可能是undefined;应封装为独立函数再调用
怎么改 hash 才不额外多一条历史记录?
用 window.location.hash = '/about',别碰 document.location.href = '#/about'。
后者会把 #/about 当作新 URL 插入 history stack,导致用户按后退键先回到一个空 hash 状态(比如 https://example.com/#),体验错乱。
window.location.hash 的 setter 会自动补 #,赋值时不用加,也不影响 pathname 或 search,行为干净可预测。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
点击普通 <a href="#about"></a> 会误触路由吗?
会。浏览器原生锚点跳转(比如页面有 <div id="about">)也会改 <code>location.hash,从而触发 hashchange,但你并不想渲染路由视图。
区分方式很简单:
- 约定路由 hash 全部以
/开头,如#/home、#/post/123 - 普通锚点用纯 ID,如
#top、#section2 - 路由处理函数里加守卫:
if (hash.startsWith('/')) { renderRoute(hash) },其他一律忽略 - 避免给 DOM 元素设
id="home"这类易混淆名
event.oldURL 和 event.newURL 能不能拿来取当前 hash?
不能。这两个字段是完整 URL 字符串(含协议、域名),且 IE8 及部分旧 WebView 不支持,属于不可靠来源。
每次读 hash,唯一可信的方式只有 location.hash。它稳定、跨浏览器、语义明确。
真正容易被忽略的是:当用户在地址栏手动编辑 hash 并回车时,hashchange 仍会触发,但你的路由 handler 必须完全可重入——不能在里面重复绑定事件、初始化全局状态或发起重复请求。否则上线后点几次链接就内存泄漏或视图错乱。










