href="javascript:" 和 href="javascript:void(0)" 的区别

72

我们的Web应用程序完全在浏览器中呈现。
服务器只通过JSON消息与浏览器通信。

因此,我们只需要一个单页面应用程序,大多数<a>标签都没有指向其他页面的真实href

在寻求去除不必要的内容时,我想知道是否可以摆脱我们代码中无用的void(0)

<a onclick="fn()">Does not appear as a link, because there's no href</a>
<a href="javascript:void(0)" onclick="fn()">fn is called</a>
<a href="javascript:" onclick="fn()">fn is called too!</a>

有人知道是否使用href="javascript:"会造成问题吗?
它甚至可以在IE7上工作...

请不要浪费你宝贵的时间告诉我内联JavaScript不好,因为这是由模板引擎生成的 :)


30
内嵌JavaScript不太好 :) - Nick Craver
@Second Rikudo,你所提到的重复问题是在这个问题之后一年才被问到的。 - Mic
@Mic 抱歉,我从审核队列中回答了这个问题,没有注意到日期(更重要的是,这个问题已经有更好的答案)。我会将重复的方向反转。 - Madara's Ghost
8个回答

59

这不会引起问题,但这是一种与PreventDefault相同的技巧。

当您在页面底部时,可以使用锚点:

<a href="#" onclick="fn()">click here</a>

如果不想跳转到页面顶部且URL还会带有锚点符号#,我们可以使用return false;或者javascript:void(0);来避免这种情况。

关于你的示例:

<a onclick="fn()">Does not appear as a link, because there's no href</a>

只需使用 a {text-decoration:underline;},你就可以得到类似链接的效果。

<a href="javascript:void(0)" onclick="fn()">fn is called</a>
<a href="javascript:" onclick="fn()">fn is called too!</a>

没问题,但在你的function最后,只需return false;以防止默认行为,不需要做更多。


我原以为没有href链接就无法工作,但实际上它可以工作,只是默认的下划线和光标不会出现。完全删除href可能是我要找的。我会进行一些检查。 - Mic
4
没有 href 的链接无法通过选项卡访问(或获取焦点),太糟糕了。 - Mic
为了让您在浏览器上拥有滚动条时能够查看行为,这里是新的修订版本:http://jsbin.com/ipoda3/2 - balexandre
1
我已经在我的页面中使用了哈希键(#)来进行导航和状态控制。我可以使用href="#",但这样就必须为所有链接添加return false,这与我现在拥有的功能相比并没有什么改进。 - Mic
是不是只有我一个人发现,Firefox只能通过Tab键聚焦并且仅允许使用Enter键激活具有href属性的锚标签?也许我的实现太差了。 - activedecay
显示剩余2条评论

26

当在导航中使用javascript:时,如果有执行脚本的返回值,它将成为显示在浏览器中的新文档的内容。JavaScript中的void运算符会导致其后的表达式返回undefined,从而防止发生此操作。你可以自己尝试一下,将以下内容复制到地址栏中并按回车键:

javascript:"hello"

结果是一个只包含单词"hello"的新页面。现在将其更改为:

javascript:void "hello"

什么也不会发生。

当您单独使用javascript:时,没有脚本被执行,因此该脚本执行的结果也是未定义的,因此浏览器什么也不做。这使得以下内容或多或少等价:

javascript:undefined;
javascript:void 0;
javascript:

除了可以通过声明一个同名变量来重写undefined之外,使用void 0基本上毫无意义,因为它已经被从void functionThatReturnsSomething()缩减到了最小。

正如其他人所提到的,与使用javascript:协议相比,在单击处理程序中使用return false;更好。


1
我同意所有的内容,除了最后一点。return falsevoid(0)一样无用,除非你使用了一个真正的href - Mic
2
@Mic:如果你使用href="#",那么你需要加上return false;,否则文档滚动会被重置。当然,如果你在链接中使用了javascript:return false也会阻止该脚本被执行,因此在这种情况下它是无用的。 - Andy E
2
将事件处理程序附加到具有“真实”URL的锚点的问题在于,如果用户以其他方式激活链接(例如,在焦点处按Enter键,中间鼠标按钮),即使他启用了Javascript,href仍然会被跟随(当然是预期行为,但仍然很烦人)。 - Yi Jiang
1
@YiJ:点击链接并按下回车键将触发onclick事件,使用中间鼠标键不太确定。 - Andy E
1
@AndyE 你知道的,返回false和事件捕获比预期的要好。 - Timo Huovinen
显示剩余5条评论

12

使用'javascript:void 0'会在IE中出现问题

当您单击该链接时,它会触发窗口的onbeforeunload事件!

<!doctype html>
<html>
<head>
</head>
<body>
<a href="javascript:void(0);" >Click me!</a>
<script>
window.onbeforeunload = function() {
    alert( 'oops!' );
};
</script>
</body>
</html>

不再支持IE 11,所以这已经成为历史了。 - ygoe

9

如果您使用jQuery事件设置onclick,此方法在所有浏览器中似乎都可以正常工作:

<a href="javascript:;">Click me!</a>

正如之前所说,href="#"会更改URL的哈希值并且可以触发数据重新加载,如果你使用历史记录(或ba-bbq)JS插件。


3

你可以将它们全部变成#

然后,在任何被onclick调用的锚点函数的末尾添加return false;,以防止页面跳到顶部。


2
我已经使用#键来进行导航和状态控制。在单页网络应用中很常见。所以我无法使用#。 - Mic
我想确认一下是否删除void(0)没有任何问题。如果我使用href="#"替代,我需要为所有的onclick添加一个return false。我认为这样并没有任何改善。 - Mic

2

通常我不使用href,而是通过CSS更改元素样式,使其看起来像链接。因此,你完全不必担心链接效果,除非是应用程序的事件处理程序。

a {
  text-recoration: underline;
  cursor: pointer;
}

1

javascript:void(0); --> 这将执行 void 函数并返回 undefined。这可能会在 IE 上出现问题。 javascript:; --> 这什么也不做。创建无效链接是最安全的选择。 '#' --> 这意味着指向同一 DOM,在单击时会重新加载页面。


0
为什么所有的点击事件都要用 a href 链接呢?
如果你使用带有 :hover CSS 和适当的 onclick 事件的 span 标签,这将完全解决这个问题。

这很激进。虽然有道理,但我不知道...我需要用A标签来创建链接。例如:对于制表符,SPAN无法获得焦点。 - Mic
1
@Mic 如果您只关心选项卡聚焦,那么给span添加tabindex属性将使其可以聚焦。 - Yi Jiang
@ji-jiang 确实,IE6喜欢在任何地方都插上它九岁的脚跟 :) - Peter Bridger
1
@ji-jiang 说实话,用 "<span tabindex..." 替换 "<a href..." 并且自己处理 tabindex 并不是一个好的选择。 - Mic
1
我不建议这样做。所有良好的语义和无障碍最佳实践都在哪里?首先,span是一个文本容器,而不是链接或操作事件。如果你想使用其他标签代替<a href=>,我认为你应该绝对使用input type="button"。 - ncubica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接