href="javascript:void(0)"是什么意思?怎么阻止链接跳转

Mason
Mason
发布时间:2026-09-18 | 4人浏览过
原创

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,浏览器不会得到一个需要显示的新文档,因此页面通常保持在当前位置,看起来就是“点击链接但没有跳转”。

SVG 配图 1
图1:javascript:void(0) 的基本执行过程,核心是执行 JavaScript 后得到 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)"
SVG 配图 2
图2:void 会执行后面的表达式,却把最终结果统一变成 undefined。

为什么它可以用来阻止链接跳转

理解这一点,需要区分普通 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 指向的地址。

SVG 配图 3
图3:推荐的处理顺序是保留真实链接,在 click 事件中通过 preventDefault() 取消本次默认导航。

什么时候应该使用 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> 的跳转关闭。

SVG 配图 4
图4:阻止跳转不是唯一目标,先判断“导航”还是“操作”,通常更容易选出合适的写法。

对应到实际代码,大致可以分成三种情况。

情况一:本来就是普通链接

<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: 写法。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表