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

IT技术 javascript html
2021-01-12 00:10:43

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

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

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

6个回答

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

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

选项1: event.preventDefault()

调用.preventDefault()传递给处理程序的事件对象方法。如果您使用 jQuery 绑定您的处理程序,则该事件将是 的一个实例,jQuery.Event并且它将是 的 jQuery 版本.preventDefault()如果您使用addEventListener绑定您的处理程序,这将是一个Event和原始DOM版本.preventDefault()无论哪种方式都会做你需要的。

例子:

$('#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 规范规定了这种行为。然而,旧版本的规范没有,所以如果你需要与旧浏览器的最大兼容性,你应该.preventDefault()显式调用有关规范详细信息,请参阅event.preventDefault() 与 return false(无 jQuery)

在这种情况下,Achilles 这样做只是因为他希望链接显示为可点击,为此他根本不需要使用 href="#"。有关更多信息,请参阅我的答案。
2021-03-15 00:10:43
发布了不需要附加点击处理程序的解决方案(晚了 3 年):stackoverflow.com/a/11246131/216941
2021-03-22 00:10:43

您可以将您的 href 设置#!#

例如,

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

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

谨防!单击时,这仍会在浏览器的历史记录中添加一个条目,这意味着在单击您的链接后,用户的后退按钮不会将他们带到他们之前所在的页面。出于这个原因,最好使用该.preventDefault()方法,或者将两者结合使用。

这是一个说明这一点的小提琴(只需向下滚动浏览器,直到出现滚动条):http :
//jsfiddle.net/9dEG7/


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

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

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

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

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

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

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

  3. fragid bytes成为百分比解码的结果fragid

  4. decoded fragid是将 UTF-8 解码器算法应用于 的结果fragid bytes如果 UTF-8 解码器发出解码器错误,则中止解码器并跳转到标记为 的步骤no decoded fragid

  5. 如果 DOM 中有一个元素的 ID 正好等于decoded fragid,那么树序中的第一个这样的元素是文档的指示部分;在这里停止算法。

  6. 无解码 fragid:如果 DOM 中有一个 a 元素的 name 属性的值恰好等于fragid( notdecoded fragid ),则树顺序中的第一个这样的元素是文档的指示部分;在这里停止算法。

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

  8. 否则,文档中没有指明的部分。

只要我们点击第 8 步并且文档中没有指定的部分,以下规则就会起作用:

如果没有指定的部分……那么用户代理什么都不做。

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

为什么不使用 href="javascript:;" 反而?据我所知,它不会改变浏览器的历史记录。在我的回答中发布了它。
2021-03-22 00:10:43
在曾经是这种方法的倡导者之后,我已经做了 180 次并建议不要使用它。请注意:这样的链接仍会更改页面 URL,从而导致浏览器历史记录中出现额外条目,并导致“后退”按钮简单地从 URL 中删除该片段,而不是执行用户期望的操作。因此,这个解决方案本身,在回答问题时,通常不是preventDefault()在点击处理程序中使用的理想替代方案- 相当可悲。
2021-04-02 00:10:43
这应该是公认的答案
2021-04-03 00:10:43
如果您输入 '!' 也没有关系 或任何其他值,只要 id 不是 DOM 的一部分。
2021-04-06 00:10:43

一种简单的方法是利用以下代码:

<a href="javascript:void(0);">Link Title</a>

这种方法不会强制页面刷新,因此滚动条保持原位。此外,它还允许您以编程方式更改 onclick 事件并使用 jQuery 处理客户端事件绑定。

由于这些原因,上述解决方案优于:

<a href="javascript:myClickHandler();">Link Title</a>
<a href="#" onclick="myClickHandler(); return false;">Link Title</a>

当且仅当 myClickHandler 方法没有失败时,最后一个解决方案将避免滚动跳转问题。

你应该改变

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

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

这样当链接被点击时页面不会滚动到顶部。这比使用 href="#" 然后阻止默认事件运行更干净。

这个问题的第一个答案中,我有很好的理由,比如return false;如果被调用的函数抛出错误,则不会执行,或者您可能将其添加return false;doSomething()函数然后忘记使用return doSomething();

不客气!
2021-03-13 00:10:43
谢谢!完全按照我的预期工作。
2021-03-26 00:10:43

从您正在调用的代码中返回 false 将起作用,并且在许多情况下是首选方法,但您也可以这样做

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

当谈到 SEO 时,它实际上取决于您的链接将用于什么。如果您打算实际使用它来链接到其他一些内容,那么理想情况下,我会同意您在这里想要一些有意义的东西,但是如果您出于功能目的使用该链接,可能就像 Stack Overflow 对帖子工具栏所做的那样(粗体、斜体、超链接)等),那么这可能无关紧要。