jQuery:如果 href 只包含 #,则防止 <a> 标记跳转

4
如果a标签的href属性中包含了一个#字符,我希望在用户点击时阻止页面跳转到顶部。因此,如果用户点击以下内容:
<a href="#">Hello</a>

不应该发生任何事情。

然而:

<a href="#target">Lorem</a>

应该像正常行为一样工作。

为什么你需要在这里添加一个链接?如果它没有任何作用的话? - Alex Sikilinda
@AlexSikilinda 这是用于下拉菜单的点击... - Henrik Petterson
2个回答

4

在jQuery中,您可以轻松完成这项任务。

$('a[href="#"]').on('click', function(e) {
    e.preventDefault();
});

如果禁止所有仅包含哈希的锚元素的默认行为,将会消除这些锚点跳转到页面顶部并滚动屏幕的情况。

使用纯JavaScript,假设支持 querySelectoraddEventListener,代码如下:

var anchors = document.querySelectorAll('a[href="#"]');

for ( var i=anchors.length; i--; ) {
    anchors[i].addEventListener('click', fn, false);
}

function fn(event) {
    event.preventDefault();
}

另一种选择是使用委派事件处理程序,正如评论中提到的那样。
$(document).on('click', 'a[href="#"]', function(e) {
    e.preventDefault();
});

直接使用DOM看起来会像这样

document.addEventListener('click', function(event) {
    var clicked = event.target;

    while ( clicked ) {
        if (clicked.nodeName.toUpperCase() === 'A' &&
            clicked.getAttribute('href') === '#') {
            event.preventDefault();
            break;
        }
        clicked = clicked.parentNode;
    }
});

很显然,委托处理程序将捕获所有的点击,并进行一些检查以查看目标是否为锚点或在锚点内,其href只为#
除非DOM中有很多锚点,否则我认为这不会更有效率。


3
这将为每个匹配元素添加一个处理程序。使用委托事件是否更好呢?#好奇 - Mackan
2
@Mackan 你应该发布一个答案,演示如何使用单个处理程序。 - Gary Woods
2
根据我的经验,委托点击处理从来不会成为性能问题。点击是用户操作,因此相对于人类时间进行评估,而不是计算机时间。点击将气泡化,所以唯一的额外时间实际上是循环检查我们是否关心点击,即使在最复杂的页面中,它也只会是 - 什么 - 20、30次迭代,顶部?(每个父/子链接一个迭代,DOM 不倾向于极其深入)。这并不意味着委托一定是正确的答案,只是一个有用的替代方案,特别是在像 jQuery 这样的好的库支持下。 - T.J. Crowder
1
@adeneo:就像我说的,委托并不一定是正确的答案。:-) 除非元素是动态添加和删除的,99%的时间我会选择直接处理程序,尽管随着我对委托的熟悉程度越来越高,我会更多地使用它。使用直接处理程序的一个原因,这个问题没有体现出来:假设我想处理点击事件并停止传播?使用委派处理程序,点击已经从元素传播到我处理它的位置,我只能阻止它进一步传播。像往常一样,选择特定工具来完成特定工作。 - T.J. Crowder
1
@adeneo:抱歉没有回答您的问题:是的,我经历过直接处理程序成为问题,但这种情况非常少见,并且与我上面没有提到的另一种委托使用有关:如果我们讨论数千个元素(比如一个大表),委托确实有助于保持内存使用率。同样,在这里不是使用案例,尽管我想OP没有告诉我们链接是什么......我对您的原始答案没有任何问题。 :-) 但是,由于您的编辑,我会再次点赞它。 - T.J. Crowder
显示剩余10条评论

1
使用“javascript:;”或“javascript.void(0)”:
<a href="javascript:;">Hello</a>
<a href="javascript.void(0)">Hello</a>

1
我需要针对我的网站上所有具有 href="#" 的 <a> 标签进行定位 -- 您的解决方案是一种内联黑客,无法针对带有哈希的 href 进行定位。 - Henrik Petterson
2
@HenrikPetterson:相较于防止其正常操作的值,什么使javascript:;更像是一种黑客行为? - T.J. Crowder

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