如何用 window.location.hash 实现基础的纯前端锚点导航功能需要先看清适用场景和关键步骤,避免只记结论却忽略实际限制。
window.location.hash锚点导航需确保目标元素id严格匹配且已存在,监听hashchange事件并手动scrollIntoView实现平滑滚动,首屏加载需额外处理location.hash,iOS优先用scrollIntoView避免scrollTop兼容问题。
window.location.hash 实现锚点导航,本质就是监听 hash 变化并滚动到对应元素——它不刷新页面、不依赖后端,但必须确保目标元素有匹配的 id,且不能只靠 href="#xxx" 就以为万事大吉。
浏览器原生锚点跳转(<a href="#section1">跳转</a>)会自动滚动,但前提是存在 <div id="section1"></div>。常见错误包括:
id 值含空格、中文或特殊字符(如 id="section 1"),应改为 id="section1" 或 id="section-1"
class 代替 id(<div class="section1"></div>),浏览器不会识别原生跳转无法加顶部偏移或自定义缓动,这时要拦截默认行为,手动滚动。关键点:
window.addEventListener('hashchange', handler),而非仅靠点击事件——用户可能直接改地址栏或点浏览器前进/后退document.getElementById(location.hash.slice(1)) 获取目标元素,注意 location.hash 带 #,需 .slice(1) 去掉el.scrollIntoView({ behavior: 'smooth', block: 'start' }) 实现平滑滚动;若需顶部留白(如固定导航栏),可改用 window.scrollTo 配合 el.offsetTop 计算位置示例片段:
window.addEventListener('hashchange', () => { const id = location.hash.slice(1); const el = document.getElementById(id); if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }});
hashchange 不会在页面首次加载时触发(即使 URL 带 hash),所以如果用户直接访问 https://site.com/#about,需要额外处理:
location.hash
hashchange 回调里,否则首屏就失效手动计算 scrollTop 在 iOS 上常因缩放、输入法弹出、导航栏高度变化而错位;scrollIntoView 是更可靠的选择:
document.body.scrollTop = offset 或 document.documentElement.scrollTop —— iOS Safari 对这两者的响应不一致scrollTo,请用 window.scrollTo({ top: offset, behavior: 'smooth' }) 并确保 offset 是基于 getBoundingClientRect().top + window.pageYOffset 动态计算真正容易被忽略的是:hash 导航不是“设了 id 就自动好使”,它依赖 DOM 存在时机、id 命名规范、以及对首次加载和浏览器差异的兜底处理。哪怕只是加个平滑滚动,漏掉初始化检查或 iOS 兼容,用户在真机上点一下就卡住,问题反而更难复现。