href="#"会滚到页首,因#是url片段标识符,浏览器默认锚定至文档开头(隐式#top),即使无匹配id也会跳转并修改地址栏;其默认行为在onclick后仍生效,须显式preventdefault()阻止。

点击 href="#" 为什么会滚到页首?
因为 # 是合法的 URL 片段标识符,浏览器默认把它当锚点处理。页面里没匹配的 id 或 name 时,就锚定到文档开头(即隐式 #top)。这不仅造成视觉跳动,还会在地址栏末尾追加 #,干扰前端路由判断,比如 React Router 的 useLocation() 会捕获这个变化,触发不必要的 popstate。
即使你绑了 onclick,这个默认行为仍会在事件执行后生效,除非显式调用 event.preventDefault()。在事件委托场景下,漏掉这句就等于白写逻辑。
href="javascript:void(0)" 真的更安全吗?
它确实不滚动、不改 URL、不触发导航,但代价是语义断裂和兼容性隐患:
- 不是真正的超链接:对键盘用户(Tab + Enter)支持不可靠,部分屏幕阅读器可能忽略其可交互性
- SEO 友好性差:搜索引擎无法理解意图,
role="button"和tabindex="0"得手动补全 - 现代框架中已被视为反模式:React 官方示例从不推荐用
<a></a>配void(0),而是倾向用<button type="button"></button> - 写法必须严格:漏掉括号(如
javascript:void 0)或空格会导致语法错误;IE 已废弃javascript:协议,Chrome 控制台有警告,CSP 策略也可能拦截
真正该用什么替代空链接?
优先级从高到低很明确:
- 用
<button type="button"></button>:语义正确、天然无跳转、键盘友好、无需额外 ARIA 属性 - 必须保留链接样式时,用
href="#"+event.preventDefault():比return false更可控,尤其在事件委托中 - 极少数老系统兼容场景下,才考虑
href="javascript:void(0)",且务必确认 CSP 允许javascript:协议
最易被忽略的一点:空链接从来不该是第一选择。如果它不跳转、不导航、也不提交,那它大概率本就不该是 <a></a> 标签——按钮、带 role 的 <div> 或封装好的组件才是更干净的解法。</div>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











