最可靠的方式是直接在点击事件回调中同步执行e.preventDefault(),绑定对象须为元素或其祖先,且需正确处理e.target;避免使用javascript:void(0)、#、return false及pointer-events:none等方案。

直接用 e.preventDefault() 是最可靠的方式
只要点击时执行了 e.preventDefault(),就能干净地阻止跳转,且不影响事件冒泡、不破坏语义、兼容性好(IE9+ 全支持)。关键不是“加没加”,而是它必须在点击事件回调里同步执行,且绑定对象得是实际被点击的 元素本身,或它的某个祖先(但要注意 e.target 可能不是 )。
常见错误:
- 内联写
onclick="handleClick()",但函数里没接收event参数 →e.preventDefault()根本调不了 - 监听父容器 click,却对
e.target类型不做判断,结果点到文字或图标也触发了阻止逻辑 - 用了
return false,它确实会阻止默认行为,但顺带把事件冒泡也干掉了,容易引发其他监听器失效
href 设成 javascript:void(0) 或 # 不推荐
这两种写法历史上常用,但现在问题明显:
-
javascript:void(0)会让 URL 栏显示空白或about:blank,影响可访问性,且部分浏览器会报 CSP 警告 -
#点击后页面会跳回顶部,尤其在长页面中体验突兀;如果页面没锚点,控制台还可能报 “Failed to execute 'scrollTo' on 'Window'” - 两者都让链接失去语义:屏幕阅读器仍会读作“链接”,但行为完全不符,不符合 WCAG 原则
真正需要禁用跳转时,优先用 JS 阻止,而不是靠伪造 href 值来“糊弄”浏览器。
用 pointer-events: none 是视觉禁用,不是行为禁用
这个 CSS 属性会让元素彻底忽略鼠标事件,包括 click、hover,看起来像“点了也没反应”。但它有硬伤:
- IE10 以下不支持,如果项目还要兼容旧 IE,这条路走不通
- 它同时屏蔽了所有交互,哪怕你后续想给这个
绑定键盘Enter触发逻辑,也一并失效 - 无法区分“临时禁用”和“永久不可用”——比如表单校验失败时禁用,校验通过后要恢复,CSS 方式就得切 class,不如 JS 控制灵活
适合场景仅限于:纯展示型链接、确定永远不响应任何用户输入、且无需键盘支持。
Vue / React 等框架里别手动操作 DOM
如果你在 Vue 里用 v-html 渲染富文本,里面含 标签,不要在 mounted 或 $nextTick 里遍历 DOM 加 addEventListener。这样既难维护,又容易漏掉动态插入的内容,还可能和框架的事件系统冲突。
更稳妥的做法:
- Vue:用自定义指令(如
v-disable-link),在mounted和updated钩子里统一处理 - React:用
useEffect+ref监听容器变化,或直接在渲染层用onClick={e => e.preventDefault()}包一层 - 服务端返回 HTML 前就过滤掉
href,或统一替换成带data-href的结构,前端只负责解析和接管
真正麻烦的从来不是“怎么阻止一次跳转”,而是“怎么在各种上下文里持续、可控、可逆地阻止跳转”。这时候硬写 e.preventDefault() 往往只是起点,不是终点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











