href="javascript:void(0)"是什么意思?怎么阻止链接跳转
href="javascript:void(0)" 是一种过去很常见的写法,它的作用是让 <a> 元素看起来仍然像链接,同时执行一段不会产生有效返回值的 JavaScript,从而避免浏览器跳转到其他页面。实际开发中虽然仍然能看到这种代码,但如果目的是“点击后执行 JavaScript,同时不跳转”,通常更推荐使用 event.preventDefault(),或者直接使用语义更合适的 <button>。
javascript:void(0) 使用了中文全角冒号“:”。真正写入 HTML 时必须使用英文半角冒号“:”,也就是 javascript:void(0)。不要直接复制全角冒号版本作为代码。
href="javascript:void(0)"到底是什么意思
先看一段最常见的代码:
<a href="javascript:void(0)">查看详情</a>
正常情况下,<a> 标签的 href 用来指定目标地址。例如:
<a href="/article/10086/">查看文章</a>
用户点击后,浏览器会打开 /article/10086/。但当 href 写成 javascript:void(0) 时,它并不是一个普通网页地址,而是一个 javascript: URL。
可以把它拆成两个部分理解:
javascript::表示后面的内容按照 JavaScript 代码处理。void(0):执行表达式0,但最终返回undefined。
由于最终结果是 undefined,浏览器不会得到一个需要显示的新文档,因此页面通常保持在当前位置,看起来就是“点击链接但没有跳转”。
void(0)中的void和0分别有什么作用
void 是 JavaScript 的一元运算符。它会执行后面的表达式,但无论表达式原来会返回什么,最终结果都变成 undefined。
例如:
console.log(void 0);
console.log(void 123);
console.log(void (1 + 2));
以上表达式的最终结果都是 undefined。这里的 0 并没有“阻止跳转”的特殊能力,它只是一个简单、安全、几乎没有额外副作用的表达式。
从 JavaScript 语法角度看,下面这些表达式也会得到 undefined:
void 0
void(0)
void 123
void("abc")
但在旧代码中,void(0) 已经形成了非常常见的固定写法,所以最容易遇到的是:
href="javascript:void(0)"
为什么它可以用来阻止链接跳转
理解这一点,需要区分普通 URL 和 javascript: URL。
下面的链接有一个真实地址:
<a href="/user/profile/">个人资料</a>
浏览器点击后会进入 /user/profile/。
而下面的代码要求浏览器执行 JavaScript:
<a href="javascript:void(0)">个人资料</a>
void(0) 的结果是 undefined,因此不会产生一个新的页面内容。最终表现就是地址没有按照普通链接进行导航。
实际项目中,它经常与点击事件一起出现:
<a href="javascript:void(0)" onclick="showMenu()">打开菜单</a>
<script>
function showMenu() {
document.getElementById('menu').hidden = false;
}
</script>
这里点击“打开菜单”时,真正要完成的是执行 showMenu(),而不是进入另一个页面。javascript:void(0) 只是让这个 <a> 标签没有正常的页面跳转目标。
现在更推荐怎样阻止链接跳转
如果一个元素本身确实是链接,只是在某些情况下需要取消默认跳转,更清晰的做法是保留真实的 href,然后在事件处理中调用 event.preventDefault()。
例如:
<a href="/user/profile/" id="profileLink">个人资料</a>
<script>
const profileLink = document.getElementById('profileLink');
profileLink.addEventListener('click', function (event) {
event.preventDefault();
console.log('已经阻止默认跳转');
});
</script>
preventDefault() 的含义非常直接:阻止这次事件对应的浏览器默认行为。对于链接的 click 事件来说,默认行为就是导航到 href 指向的地址。
什么时候应该使用 preventDefault()
适合这种场景:
<a href="/delete/123" id="deleteLink">删除</a>
点击以后,需要先弹出确认框。用户取消时不跳转,确认以后再继续处理:
<a href="/delete/123" id="deleteLink">删除</a>
<script>
const deleteLink = document.getElementById('deleteLink');
deleteLink.addEventListener('click', function (event) {
const confirmed = window.confirm('确定要继续吗?');
if (!confirmed) {
event.preventDefault();
}
});
</script>
这里和 javascript:void(0) 的区别很明显:链接本身仍然拥有真实目标,只是在满足特定条件时取消浏览器的默认行为。
如果根本不需要跳转,最好直接使用button
有些页面把所有可点击元素都写成 <a>,于是出现大量这样的代码:
<a href="javascript:void(0)" onclick="openDialog()">打开设置</a>
但“打开设置弹窗”实际上不是网页导航,而是一个操作动作。这种情况下更合适的是:
<button type="button" id="openSettings">打开设置</button>
<script>
document.getElementById('openSettings').addEventListener('click', function () {
openDialog();
});
</script>
<button> 本身就不会像普通链接那样根据 href 导航,因此不需要额外使用 void(0) 来“阻止跳转”。
判断时可以记住一个简单原则:
- 用户点击以后是“去另一个地址”——优先使用
<a href="真实地址">。 - 用户点击以后是“执行一个操作”——优先使用
<button type="button">。 - 链接确实有目标地址,但这一次需要根据条件取消跳转——使用
event.preventDefault()。
href="#"和javascript:void(0)有什么区别
另一种老代码中经常出现的写法是:
<a href="#">点击</a>
它和 javascript:void(0) 看起来都可能没有打开新页面,但行为并不完全一样。
href="#" 是一个片段链接。单独的 # 会参与当前文档的 URL 导航,通常还可能影响页面滚动位置或地址栏中的 URL。
例如:
<a href="#settings">跳到设置区域</a>
...
<section id="settings">
设置内容
</section>
这种使用 #settings 的方式有实际意义,因为它用于跳转到当前页面中 ID 为 settings 的元素。
但如果只是为了制造一个“不会跳去其他页面”的假链接:
<a href="#" onclick="openMenu()">打开菜单</a>
那么通常还需要使用 preventDefault():
<a href="#" id="menuLink">打开菜单</a>
<script>
document.getElementById('menuLink').addEventListener('click', function (event) {
event.preventDefault();
openMenu();
});
</script>
| 写法 | 实际含义 | 是否适合作为现代代码的首选 |
|---|---|---|
href="javascript:void(0)" |
执行 JavaScript,并通过 void 得到 undefined | 通常不建议作为新代码首选 |
href="#" |
指向当前文档的片段位置 | 有真实锚点用途时使用,不适合单纯充当空链接 |
event.preventDefault() |
在事件处理过程中取消浏览器默认行为 | 链接需要按条件取消导航时更清晰 |
<button type="button"> |
表示一个操作按钮,没有链接默认跳转行为 | 执行弹窗、切换、提交外操作等动作时更合适 |
return false也能阻止链接跳转吗
在 HTML 内联事件中,经常还能看到:
<a href="/article/10086/" onclick="return false;">文章详情</a>
这里点击以后不会按照 href 跳转,因为内联事件处理器返回了 false。
也可以写成:
<a href="/article/10086/" onclick="return checkLink();">文章详情</a>
<script>
function checkLink() {
return false;
}
</script>
不过在使用 addEventListener() 注册事件时,不应该认为简单的 return false 就等同于 preventDefault()。
例如下面这种写法:
link.addEventListener('click', function (event) {
return false;
});
不要把它当作取消原生默认导航的标准方法。使用原生事件监听器时,应明确写出:
link.addEventListener('click', function (event) {
event.preventDefault();
});
这样代码的意图也更加清楚:这里就是要阻止当前点击事件对应的默认操作。
为什么不建议大量使用javascript:void(0)
javascript:void(0) 并不是看到就必须删除的“错误语法”。维护旧项目时,如果已有代码依赖这种写法,而且行为明确,它仍然可能正常工作。
问题主要在于,新代码通常有更清晰的实现方式。
1. 把行为写进了href
href 本来的主要用途是描述链接目标:
<a href="/products/">产品列表</a>
而:
<a href="javascript:void(0)">产品列表</a>
并没有告诉浏览器这个链接真正应该去哪里。如果元素实际上只是执行操作,那么用 button 更符合元素本身的用途。
2. javascript: URL容易和业务逻辑混在一起
旧代码中甚至可能出现:
<a href="javascript:openDialog()">打开窗口</a>
这种方式把 JavaScript 直接塞进 HTML 属性。随着功能变多,事件逻辑会越来越难整理。更容易维护的结构通常是:
<button type="button" id="openDialogButton">打开窗口</button>
<script>
const button = document.getElementById('openDialogButton');
button.addEventListener('click', openDialog);
</script>
3. 容易掩盖元素类型选择错误
如果一个“链接”永远都没有导航目标,真正的问题可能不是“怎样阻止它跳转”,而是它本来就不应该使用链接元素。
例如展开下拉菜单:
<button type="button" id="categoryButton">选择分类</button>
通常比下面这种方式更直接:
<a href="javascript:void(0)" id="categoryButton">选择分类</a>
实际开发中该怎么选择
可以从“点击以后到底要做什么”开始判断,而不是先考虑怎样把 <a> 的跳转关闭。
对应到实际代码,大致可以分成三种情况。
情况一:本来就是普通链接
<a href="/article/10086/">阅读全文</a>
直接保留正常的 href,没有必要阻止跳转。
情况二:有链接地址,但当前条件下不允许跳转
<a href="/checkout/" id="checkoutLink">去结算</a>
<script>
const checkoutLink = document.getElementById('checkoutLink');
const cartIsEmpty = true;
checkoutLink.addEventListener('click', function (event) {
if (cartIsEmpty) {
event.preventDefault();
alert('购物车为空,暂时不能结算');
}
});
</script>
这种情况适合使用 preventDefault(),因为 /checkout/ 本身仍然是一个真实目标,只是当前条件不允许进入。
情况三:点击只是执行操作,从来都不需要导航
<button type="button" id="toggleMenu">展开菜单</button>
<script>
document.getElementById('toggleMenu').addEventListener('click', function () {
document.getElementById('menu').hidden =
!document.getElementById('menu').hidden;
});
</script>
这时直接使用 button,通常比制造一个空链接更自然。
几个容易写错的地方
不要把中文冒号写进javascript:
正确:
<a href="javascript:void(0)">点击</a>
错误示例:
<a href="javascript:void(0)">点击</a>
第二种使用的是中文全角冒号 :。它不是 javascript: URL 所要求的 ASCII 半角冒号,因此不能把两种写法当作同一段代码。
不要以为void(0)会停止后面的JavaScript代码
void(0) 的作用不是“中断 JavaScript”。例如:
console.log('A');
void(0);
console.log('B');
这段代码中的两个 console.log() 都可以继续执行。void 只是改变表达式的返回结果,并不是类似 return 的流程控制语句。
preventDefault()只取消默认行为
下面的代码:
link.addEventListener('click', function (event) {
event.preventDefault();
console.log('点击事件仍然执行');
});
会阻止链接导航,但不会停止整个事件处理函数。后面的 console.log() 仍然会执行。
因此要区分三个概念:
preventDefault():阻止浏览器默认行为。stopPropagation():阻止事件继续向祖先元素传播。return:结束当前 JavaScript 函数的执行。
它们解决的是不同问题,不能因为名称都带有“停止”的感觉就互相替代。
总结
href="javascript:void(0)" 的本质并不是一个特殊的“禁止跳转属性”。其中 javascript: 表示执行 JavaScript,void(0) 则执行表达式并返回 undefined,于是不会像普通 href 那样导航到另一个网页。
维护旧项目时遇到这种写法,知道它为什么不会跳转即可。编写新代码时,可以根据实际目的选择更明确的实现方式:真正的导航使用正常 <a href="...">;链接需要根据条件取消导航时调用 event.preventDefault();如果点击只是执行弹窗、展开菜单、切换状态等操作,则优先使用 <button type="button">。
还要特别注意,正确代码是 javascript:void(0),冒号必须是英文半角 :。标题中的 javascript:void(0) 如果原样复制到代码中,因为使用了中文全角冒号,并不等同于标准的 javascript: 写法。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













