防止 href="#" 链接改变URL哈希值

60

我有一个已经利用URL中的哈希的网站,我不想改变它。当我使用Zurb Foundation并使用 href="#"来创建菜单项时,点击它会删除先前的哈希值。

如何覆盖这种行为?

更新:我认为最好保持使用 <a> 元素,因为如果我改变它,会影响绑定到该HTML元素的样式。在使用设计框架时,我总是喜欢保持默认约定而不是乱修改CSS属性。

谢谢。


我只是遵循Zurb Foundation文档,他们在菜单项链接中使用href="#"。 - Liron Harel
空着也是有效的。 - user2587132
你能粘贴一下你的菜单HTML吗?一个什么都不做的菜单有什么意义呢? - Max Hoffmann
它确实有每个<a>元素的onclick事件 - 我已经添加了它。 - Liron Harel
@user2587132 那是个好主意:它非常有效!在我的测试中使用 href="" 现在可以正常工作:不再需要更改 URL,而且链接样式看起来正确。 - Raymond Naseef
11个回答

47
你可以监听点击事件并调用preventDefault来阻止浏览器设置哈希(hash值)。
使用jQuery的示例:
$('.mylink').click(function(event){
    event.preventDefault();
});

4
你还可以使用return false,它是event.preventDefaultevent.stopPropagation的简写。 - Ben Sewards

40

你可以使用javascript:;替代#来作为href属性,这样不会改变URL。

<a href="javascript:;">:Link</a>

3
应该使用按钮元素,而不是这样做。 - Max Hoffmann
3
正如我之前所说,我需要使用<a>标签,因为Foundation已经附加了样式,而且我更喜欢按照他们的样式和代码约定进行工作。(http://foundation.zurb.com/docs/components/dropdown.html) - Liron Harel

40

请了解 渐进增强优雅降级

几乎永远不要使用href="#"。这是一个链接到未定义锚点的链接(它将指向页面顶部)。通常使用它的人是因为他们想通过它来实现 JavaScript 的效果。

如果你要使用链接,那么它应该指向有用的地方。通常这将是另一个页面,该页面使用服务器端技术以获得与 JavaScript 相同的效果(尽管速度可能会慢一些)。然后您可以防止链接的正常行为。

例如:

<a href="/foo/bar" class="whatever">Foo: Bar</a>

使用该脚本:

addEventListener('click', function (ev) {
    if (ev.target.classList.contains('whatever')) {
        ev.preventDefault();
        loadWithAjax(ev.target.href);
    }   
});
如果JavaScript所做的事情无法用链接表达等效功能,则首先不应该使用链接。使用<button>,并严肃考虑使用JavaScript/DOM将其添加到文档中,而不是HTML。
(注:相当多的人希望支持不识别classListaddEventListener的旧浏览器检查浏览器支持并查找兼容性程序留给读者作为练习。使用YUI、jQuery或类似工具是处理兼容性的一种方法。)

谢谢。他们使用<a>标签来设置样式。如果我将其删除,就会改变样式,因此我更喜欢遵循他们的代码约定(http://foundation.zurb.com/docs/components/dropdown.html),而不是进行css调整。 - Liron Harel
为什么要认真考虑使用JavaScript/DOM将其添加到文档中,而不是使用HTML呢? - user2587132
2
这样做可以避免在JS加载失败时出现无法使用的UI控件。 - Quentin
有时候你需要在下拉列表中使用<a>标签来作为菜单项,使用Spectre CSS。如果没有设置href属性,光标不会变成pointer,我猜你可以覆盖样式,但是这太麻烦了... - user9645
@user9645 — 看了你提供的例子,那些链接应该是常规链接,href 属性包含有用的 URL。它们不应该使用 href="#"(示例中的代码只是占位符),因此我的答案仍然有效。 - Quentin
我同意 href="#" 很丑陋。在当今的网站上,很难说链接应该如最初设计的那样仅用于重新加载不同的页面(或当前页面上的位置)。 - Raymond Naseef

17

12

只需要使用这个:

<a href="javascript:void()">text</a>

有时候你无法避免使用 # target。例如当使用 Foundation 组件(选项卡)时。 - Mark Ibanez

6

我已经采取以下措施来防止带有 href="#" 属性的所有标签执行导航(使用 JQuery):

$('a[href$="#"]').click(function (event) {
            event.preventDefault ? event.preventDefault() : event.returnValue = false;

        });

美元符号 (a[href$="#"]) 是一个打字错误吗? - code
@code 这是“属性以...结尾”的选择器:https://api.jquery.com/attribute-ends-with-selector/ - Cocowalla

4

这对我来说有效。

$(document).on('click', 'a', function (e) {
    if ($(this).attr('href') == '#') {
        e.preventDefault();
    }
});

2

请将以下代码添加到您的默认库中。
当点击事件发生时,它将获取href值,并且如果发现哈希(#)值,则会阻止默认事件,从而避免重定向到href值。

$(document).on('click', 'a', function (e) {
    if ($('#'+e.target.id).attr('href')=='#') {
        e.preventDefault();
    }
});

1
我遇到的最短的方法就是使用语句结束符号:
<a href="javascript:;" class="ouvrir">Newsletter</a>

1
这样做的最简单方式是<a href="#hash" onclick="event.preventDefault();"></a>

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