JavaScript - 超链接的href与onclick在回调函数中有什么区别?

564

我希望在点击事件时运行一个简单的JavaScript函数,而不进行任何重定向。

将JavaScript调用放在 href 属性中(像这样)与使用 onclick 有什么区别或好处吗?

<a href="javascript:my_function();window.print();">....</a>

将其放入onclick属性(绑定到onclick事件) vs. 不将其放入onclick属性?


7
这个问题之前已经讨论过:https://dev59.com/gnVC5IYBdhLWcg3wlyMo ,请注意查看该链接。 - SolutionYogi
2
以及https://dev59.com/YHVC5IYBdhLWcg3w9GLM - Sampson
20个回答

1114

bad:

不好的:

<a id="myLink" href="javascript:MyFunction();">link text</a>

好的:

<a id="myLink" href="#" onclick="MyFunction();">link text</a>

更好的:

<a id="myLink" href="#" onclick="MyFunction();return false;">link text</a>

更好的例子1:

<a id="myLink" title="Click to do something"
 href="#" onclick="MyFunction();return false;">link text</a>

更好的方法 2:

<a id="myLink" title="Click to do something"
 href="PleaseEnableJavascript.html" onclick="MyFunction();return false;">link text</a>

为什么更好?因为 return false 将阻止浏览器跟随链接。

最佳方法:

使用jQuery或其他类似的框架通过元素的ID附加onclick处理程序。

$('#myLink').click(function(){ MyFunction(); return false; });

27
有另外一种最好的解决方案,那就是对于无JS浏览器,href不设置为#,而是设置为实际链接。 - helly0d
7
如果我告诉你,只有第一个(不好的)在所有浏览器中使用中键单击的方式是相同的,你会怎么想? - Vloxxity
19
关于<a id="myLink" href="javascript:MyFunction();">有什么不好的呢? - Kartick Vaddadi
8
仅是我的个人意见:最好的选择是使用按钮进行点击(onclick事件?),并将锚点保留其原始设计意图,即作为链接到其他页面的锚点。 - nidalpres
11
但是,为什么是不好的?为什么是好的?为什么更好?为什么更加更好1?为什么更加更好2?为什么是最好的?只要它有效果,就可以。 - Baim Wrong
显示剩余22条评论

309

将 onclick 放在 href 内会冒犯那些坚信内容与行为应该分离的人。他们认为你的 HTML 内容应该仅关注内容本身,而不是呈现或行为。

如今的典型做法是使用 JavaScript 库(如 jQuery)并创建一个事件处理器。它看起来会像这样:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );

1
或者是MooTools、Prototype、Dojo……或者直接使用JavaScript,但这会增加很多代码量,不过这也值得一试。 - Ryan Florence
17
如果你不需要处理事件对象,那么纯JavaScript非常简单。使用 obj = document.getElementById() 获取DOM节点,然后设置 obj.onclick = foo。 - Matt Bridges
9
但是问题不是在询问将JS调用放在href中与将其放在onclick中的区别吗?假设出于某种原因您要将其内联,应该使用哪个?(实际上,我会按照您建议的做法去做,但您似乎忽略了这两个属性之间的差异。) - nnnnnn
2
我唯一会主张将函数调用放在内联而不是为链接设置onclick事件的情况是,如果您正在页面内动态创建链接,并且这些链接都将调用相同的函数但可能没有唯一的ID。我有一个Web表单,用户可以添加和删除项目,我将onclick放在动态创建的div中的链接的href中,以便我可以更快地开始处理脚本,而不是使用相对ID或类名等不太具体的东西。 - MistyDawn
1
我非常不同意“内容与行为分离”的想法。当你坚持这一点时,内容和行为之间的联系就不明显了。那么你怎么知道行为在哪里呢?现在你必须通过id或class进行搜索,这是一个问题。通常会返回多个结果——你要找的是哪一个?你必须阅读所有的代码才能弄清楚。这非常低效。现在把函数定义放在内容中也是不好的,所以有时候走得太远也是不好的。 - Jason Cheng
显示剩余3条评论

75
在JavaScript中,其中一个区别是在onclick处理程序中的this关键字将引用其onclick属性所在的DOM元素(在本例中为<a>元素),而href属性中的this将引用window对象。
在显示方面,如果链接中缺少href属性(即<a onclick="[...]">),默认情况下浏览器将显示text光标(而不是通常所需的pointer光标),因为它把<a>视为锚点而不是链接。
在行为方面,当通过href导航指定操作时,浏览器通常支持使用快捷方式或上下文菜单在单独的窗口中打开那个href。当仅通过onclick指定操作时,这是不可能的。
然而,如果你想知道从DOM对象的点击获取动态操作的最佳方法是什么,那么使用JavaScript分离文档内容以绑定事件是最好的方法之一。你可以通过多种方式完成这个过程。一种常见的方式是使用类似jQuery的JavaScript库来绑定事件:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<a id="link" href="http://example.com/action">link text</a>
<script type="text/javascript">
    $('a#link').click(function(){ /* ... action ... */ })
</script>

10
感谢您确认了我的猜测,“href”与“onclick”中的“this”是不同的。 - joonas.fi

19

编辑警告:请查看评论,这个答案中使用'nohref'是不正确的。

我使用

Click <a nohref style="cursor:pointer;color:blue;text-decoration:underline"
onClick="alert('Hello World')">HERE</a>

有更简洁的方法,但这是可行的。使用"A"样式可以简化代码:

<style> A {cursor:pointer;color:blue;text-decoration:underline; } </style> 
<a nohref onClick="alert('Hello World')">HERE</a>

11
+1 真的很棒!:-) 我以前从未听说过 nohref 属性。这是处理此类 JavaScript 操作最合乎逻辑/优雅的方式。它与 FF12 和 IE8 兼容。因此,我将用 nohref 替换所有的 href="JavaScript:void(0);"。非常感谢。干杯。 - oHo
7
它不受主要浏览器支持,我们为什么要使用它?http://www.w3schools.com/tags/att_area_nohref.asp - hetaoblog
13
“nohref” 是 “area” 标签的一部分,而不是 “a” 标签!你的示例与 <a onClick="alert('Hello World')">HERE</a> 相同。 - nZeus
8
只是另一个“不要这样做的警告”。这完全是非标准和错误的建议。在a标签上不存在nohref属性。 - Colin 't Hart

17
顶部答案是一个非常糟糕的实践,绝不能链接到空哈希,因为这可能会在后期引起问题。最好将事件处理程序绑定到元素上,就像众多其他人所述一样。但是,在每个现代浏览器中,<a href="javascript:doStuff();">做事情</a>都能完美运行,我在渲染模板时广泛使用它,以避免为每个实例重新绑定。在某些情况下,这种方法提供了更好的性能。因人而异。

另一个有趣的小贴士...

onclickhref在直接调用JavaScript时具有不同的行为。

onclick将正确地传递this上下文,而href不会,或者换句话说,<a href="javascript:doStuff(this)">无上下文</a>将无法工作,而<a onclick="javascript:doStuff(this)">无上下文</a>将可以。

是的,我省略了href。虽然这不符合规范,但在所有浏览器中都可以工作,尽管理想情况下应该包括href="javascript:void(0);"以确保安全。


感谢这个帮助,希望它能够在列表中排名更高。我一直在为那些#问题苦苦挣扎。顺便说一句,我注意到即使我使用JS分配了单击处理程序,href="javascript:void(0);"仍然是一个好主意,因为如果没有href,链接的UI就不太对(至少在Chrome上,它会失去默认的鼠标光标和链接颜色)。 - Jason C

13

最好的方法是使用:

<a href="#" onclick="someFunction(e)"></a>
问题在于这会在浏览器中在页面 URL 的末尾添加一个哈希(#),因此需要用户点击两次后退按钮才能返回到您之前的页面。鉴于此,您需要添加一些代码来停止事件传播。大多数 JavaScript 工具包已经有了此功能。例如,dojo 工具包使用的是:
dojo.stopEvent(event);

要这样做。


11
我想提醒你,如果你使用href="#",浏览器将会寻找一个已命名的锚点标签,但由于它找不到,所以会使窗口滚动到页面顶部。如果你已经在页面顶部,这可能不会被注意到。 为了避免这种行为,请改用:href="javascript:;" - alonso.torres
1
@alonso.torres 不错的观点,但这就是我提到使用dojo.stopEvent()的原因 - 它将停止事件传播/冒泡和单击锚的默认行为。 - linusthe3rd
7
为什么不直接返回false(onclick="someFunction(e);return false;"),而不是使用stopEvent? - stracktracer

11

除此之外,href会在浏览器的状态栏中显示,而onclick则不会。我认为在那里显示JavaScript代码并不友好。


9

这个有效

<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>

3
欢迎来到 Stack Overflow!虽然这段代码可能能够解决问题,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,这些人可能不知道您提出代码建议的原因。同时,请尽量不要在代码中添加过多的解释性注释,因为这会降低代码和解释的可读性! - Blue

8
在非脚本特定属性中使用javascript:是一种过时的HTML方法。虽然从技术上讲它可以工作,但您仍然将javascript属性分配给非脚本属性,这并不是一个好的实践。它甚至可能在旧浏览器上失败,甚至在一些现代浏览器上(似乎谷歌的论坛帖子表明Opera不喜欢“javascript:”URL)。
更好的做法是第二种方式,将您的javascript放入onclick属性中,如果没有可用的脚本功能,则会被忽略。在href字段中放置一个有效的URL(通常为“#”),以备那些没有JavaScript的人使用。

1
我不明白在没有启用JavaScript的浏览器中,“javascript:” href和带有onclick属性的“#” href之间有什么区别。对于这两种情况,都对浏览器没有启用JS的用户来说是同样无用的。 - harto
2
harto,那并不正确。 '#'是命名链接的指示符,它不是JavaScript标识符。它是一个有效的URL,并且不需要JavaScript才能被识别。 - zombat

8

我使用以下代码行使它对我起作用:

<a id="LinkTest" title="Any Title"  href="#" onclick="Function(); return false; ">text</a>

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