如何阻止网页在点击触发 JavaScript 的链接时滚动到顶部?

2022-08-30 02:38:01

当我有一个链接与jQuery或JavaScript事件连接时,例如:

<a href="#">My Link</a>

如何防止页面滚动到顶部?当我从锚点中删除 href 属性时,页面不会滚动到顶部,但链接似乎无法单击。


答案 1

您需要防止发生点击事件的默认操作(即导航到链接目标)。

有两种方法可以做到这一点。

选项 1:event.preventDefault()

调用传递给处理程序的事件对象的方法。如果您使用 jQuery 绑定处理程序,则该事件将是 jQuery.Event 的一个实例,它将是 .preventDefault() 的 jQuery 版本。如果您用于绑定处理程序,它将是一个事件.preventDefault() 的原始 DOM 版本。无论哪种方式都可以满足您的需求。.preventDefault()addEventListener

例子:

$('#ma_link').click(function($e) {
    $e.preventDefault();
    doSomething();
});

document.getElementById('#ma_link').addEventListener('click', function (e) {
    e.preventDefault();
    doSomething();
})

选项 2:return false;

在 jQuery 中

从事件处理程序返回 false 将自动调用 event.stopPropagation() 和 event.preventDefault()

因此,使用jQuery,您可以使用此方法来防止默认链接行为:

$('#ma_link').click(function(e) {
     doSomething();
     return false;
});

如果您使用的是原始DOM事件,这也适用于现代浏览器,因为HTML 5规范规定了此行为。但是,旧版本的规范没有,因此如果您需要与旧浏览器的最大兼容性,则应显式调用。有关规范的详细信息,请参阅 event.preventDefault() vs. return false (no jQuery)。.preventDefault()


答案 2

您可以将 href 设置为 而不是#!#

例如

<a href="#!">Link</a>

单击时不会进行任何滚动。

小心!单击时,这仍将向浏览器的历史记录添加一个条目,这意味着单击链接后,用户的后退按钮不会将他们带到以前所在的页面。因此,最好使用 .preventDefault() 方法,或者同时使用两者。

这里有一个小提琴来说明这一点(只需向下挤压浏览器,直到得到一个滚动条):
http://jsfiddle.net/9dEG7/


对于规范书- 为什么这有效:

此行为在 HTML5 规范的“导航到片段标识符”部分下指定。带有 href 的链路导致文档滚动到顶部的原因是,此行为被显式指定为处理空片段标识符的方式:"#"

如果 fragid 是空字符串,则文档的指示部分是文档的顶部

使用 href 代替工作,只是因为它避免了此规则。感叹号没有什么神奇之处 - 它只是一个方便的片段标识符,因为它与典型的碎片明显不同,不太可能与页面上的元素或匹配。实际上,我们可以在哈希之后放置几乎任何东西;唯一不够的fragid是空字符串,单词“top”或与页面上元素匹配或属性的字符串。"#!"idnamenameid

更确切地说,我们只需要一个片段标识符,它将使我们在以下算法中落入步骤8,用于从fragid中确定文档的指示部分

  1. 将 URL 解析器算法应用于 URL,并让 fragid 成为生成的解析 URL 的片段组件。

  2. 如果 fragid 是空字符串,则文档的指示部分是文档的顶部;在此处停止算法。

  3. fragid 字节成为百分比解码 fragid 的结果。

  4. 解码的 fragid 是将 UTF-8 解码器算法应用于 fragid 字节的结果。如果 UTF-8 解码器发出解码器错误,请中止解码器,转而跳转到标记为“无解码碎片”的步骤

  5. 如果DOM中有一个元素的ID与解码的fragid完全相等,那么树顺序中的第一个这样的元素是文档的指示部分;在此处停止算法。

  6. 没有解码的fragid:如果DOM中有一个元素具有一个名称属性,其值正好等于fragid解码的fragid),那么树顺序中的第一个这样的元素是文档的指示部分;在此处停止算法。

  7. 如果 fragid 是字符串的 ASCII 不区分大小写匹配,则文档的指示部分是文档的顶部;在此处停止算法。top

  8. 否则,文档没有指示部分。

只要我们点击步骤 8 并且文档没有指示的部分,以下规则就会发挥作用:

如果没有指示的部分...则用户代理必须不执行任何操作。

这就是为什么浏览器不滚动的原因。