对于 JavaScript 链接,我应该使用哪个“href”值,“#”还是“javascript:void(0)”?
以下是两种构建链接的方法,其唯一目的是运行 JavaScript 代码。从功能、页面加载速度、验证目的等方面来看,哪种方法更好?
function myJsFunc() {
alert("myJsFunc");
}
<a href="#" onclick="myJsFunc();">Run JavaScript Code</a>
或
function myJsFunc() {
alert("myJsFunc");
}
<a href="javascript:void(0)" onclick="myJsFunc();">Run JavaScript Code</a>
我使用
javascript:void(0)
。
有三个原因。鼓励开发人员团队使用
#
不可避免地会导致一些人使用被调用函数的返回值,如下所示:
function doSomething() {
//Some code
return false;
}
但是他们忘记在 onclick 中使用
return doSomething()
,而只是使用
doSomething()
。
避免使用
#
的第二个原因是,如果被调用函数抛出错误,则最终的
第三个原因是,有些情况下
onclick
事件属性是动态分配的。我更喜欢能够调用函数或动态分配它,而不必专门为一种或另一种附加方法编写函数代码。因此,我的 HTML 标记中的
onclick
(或任何内容)如下所示:
onclick="someFunc.call(this)"
或
onclick="someFunc.apply(this, arguments)"
使用
javascript:void(0)
可避免上述所有麻烦,而且我还没有发现任何缺点的例子。
因此,如果您是一名单独的开发人员,那么您显然可以做出自己的选择,但如果您以团队形式工作,则必须声明:
使用
href="#"
,确保
onclick
始终在末尾包含
return false;
,任何调用的函数都不会引发错误,并且如果您将函数动态附加到
onclick
属性,请确保它不仅不会引发错误,而且还返回
false
。
或
使用
href="javascript:void(0)"
第二种显然更容易沟通。
都不是。
如果您有一个实际有意义的 URL,请将其用作 HREF。如果有人在您的链接上单击鼠标中键以打开新选项卡或禁用了 JavaScript,则不会触发 onclick。
如果这不可能,那么您至少应该使用 JavaScript 和适当的点击事件处理程序将锚标记注入文档。
我知道这并不总是可行的,但在我看来,在开发任何公共网站时都应该努力实现这一点。
查看 Unobtrusive JavaScript 和 Progressive reinforcement reinforcement (均来自维基百科)。
执行
<a href="#" onclick="myJsFunc();">Link</a>
或
<a href="javascript:void(0)" onclick="myJsFunc();">Link</a>
或任何其他包含
onclick
属性的操作 - 五年前是可以的,但现在这可能是一种不好的做法。原因如下:
-
它促进了侵入性 JavaScript 的实践 - 事实证明这种实践难以维护且难以扩展。有关此内容的更多信息,请参阅 非侵入式 JavaScript 。
-
您花时间编写极其冗长的代码 - 这对代码库几乎没有任何好处(如果有的话)。
-
现在有更好、更简单、更易于维护和可扩展的方法来实现所需的结果。
非侵入式 JavaScript 方式
完全不要使用
href
属性!任何好的 CSS 重置都会解决缺少的默认光标样式,因此这不是问题。然后使用优雅且不引人注目的最佳实践附加您的 JavaScript 功能 - 由于您的 JavaScript 逻辑保留在 JavaScript 中而不是您的标记中,因此更易于维护 - 当您开始开发需要将您的逻辑拆分为黑盒组件和模板的大型 JavaScript 应用程序时,这一点至关重要。有关此内容的更多信息,请参阅
大规模 JavaScript 应用程序架构
简单代码示例
// Cancel click event
$('.cancel-action').click(function(){
alert('Cancel action occurs!');
});
// Hover shim for Internet Explorer 6 and Internet Explorer 7.
$(document.body).on('hover','a',function(){
$(this).toggleClass('hover');
});
a { cursor: pointer; color: blue; }
a:hover,a.hover { text-decoration: underline; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="cancel-action">Cancel this action</a>
黑盒 Backbone.js 示例
有关可扩展、黑盒、Backbone.js 组件示例 - 请参阅此处的 jsfiddle 工作示例 。请注意我们如何利用不显眼的 JavaScript 实践,并在极少量的代码中拥有一个可以在页面上多次重复的组件,而不会产生副作用或不同组件实例之间的冲突。太棒了!
注释
-
省略
a
元素上的href
属性将导致无法使用tab
键导航访问该元素。如果您希望通过tab
键访问这些元素,您可以设置tabindex
属性,或改用button
元素。您可以轻松地将按钮元素的样式设置为看起来像普通链接,如 Tracker1 的答案 中所述。 -
省略
a
元素上的href
属性将导致 Internet Explorer 6 和 Internet Explorer 7 不采用a:hover
样式,这就是为什么我们添加了一个简单的 JavaScript 垫片来通过a.hover
实现此目的。这完全没问题,因为如果您没有 href 属性,也没有优雅降级,那么您的链接无论如何都不会起作用 - 您将有更大的问题需要担心。 -
如果您希望您的操作在禁用 JavaScript 的情况下仍然有效,那么使用带有
href
属性的a
元素,该元素转到某个将手动执行操作的 URL,而不是通过 Ajax 请求或其他方式执行操作。如果您正在这样做,那么您需要确保在单击调用时执行event.preventDefault()
,以确保单击按钮时它不会跟随链接。此选项称为优雅降级。