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


135

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

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

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

Answers:


197

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

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

选项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()与返回false(无jQuery)以获取详细规范。


9
发布了不需要附加点击处理程序的解决方案(延迟了3年):stackoverflow.com/a/11246131/216941
Matt Crinklaw-Vogt 2012年

在这种情况下,Achilles只是这样做,因为他希望链接显示为可点击的,为此他根本不需要使用href =“#”。查看我的答案以获取更多信息。
achecopar

164

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

例如,

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

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

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

这是一个小提琴,它对此进行了说明(只需将浏览器向下滚动直到获得滚动条):http :
//jsfiddle.net/9dEG7/


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

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

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

使用href "#!"代替而是仅因为避免了此规则而起作用。感叹号没有什么魔力-它只是一个方便的片段标识符,因为它与典型的脆弱标识符明显不同,并且不太可能匹配页面上的idname元素。确实,我们可以将几乎所有内容都放在哈希后面;唯一不能满足要求的是空字符串,单词“ top”或与页面上元素匹配nameid属性的字符串。

更准确地说,我们只需要一个片段标识符,该标识符将使我们进入以下算法中的步骤8,从而从脆弱的对象中确定文档指示部分

  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. 没有经过解码的脆弱:如果DOM中存在一个元素,其名称属性的值恰好等于fragidnotdecoded fragid),则树形顺序中的第一个此类元素是文档的指示部分;在此处停止算法。

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

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

只要我们执行步骤8,并且文档中没有指示的部分,就会遵循以下规则:

如果没有指示的部分...,那么用户代理将不执行任何操作。

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


4
放'!'没关系 或任何其他值,只要id不属于DOM。
Gopinath

3
曾经是这种方法的倡导者之后,我已经做了180次并提出了建议。当心:这样的链接仍将更改页面URL,从而在浏览器的历史记录中产生一个额外的条目,并导致“后退”按钮仅从URL中删除该片段,而不执行用户期望的操作。因此,这种解决方案在回答所要求的问题时,通常不是preventDefault()在单击处理程序中使用的理想替代方法-遗憾的是。
Mark Amery

1
为什么不使用href =“ javascript :;” 代替?据我所知,它不会更改浏览器的历史记录。关于它的贴在我的答案上。
achecopar

30

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

<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方法不会失败时,最后一种解决方案才能避免出现滚动跳转问题。


12

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

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

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


9

您应该更改

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

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

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

我对第一个答案很好的理由对这个问题,就像return false;如果调用的函数抛出一个错误将不执行,或者可能添加return false;doSomething()函数,然后忘了使用return doSomething();



4

如果您可以简单地更改该href值,则应使用:

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

我刚想出的另一种巧妙的解决方案是使用jQuery来阻止单击动作的发生并导致页​​面滚动,但仅限于href="#"链接。

<script type="text/javascript">
    /* Stop page jumping when links are pressed */
    $('a[href="#"]').live("click", function(e) {
         return false; // prevent default click action from happening!
         e.preventDefault(); // same thing as above
    });
</script>

当然return false应该在preventDefault()第二行之后,否则您将永远无法到达第二行?
hobailey '16


2

另外,您可以在onclick属性中使用event.preventDefault

<a href="#" onclick="event.preventDefault(); doSmth();">doSmth</a>

无需编写exstra click事件。


0

您也可以像这样简单地写:

<a href="#!" onclick="function()">Delete User</a>

0

调用该函数时,请遵循以下return false 示例:

<input  type="submit" value="Add" onclick="addNewPayment();return false;">

0

创建一个包含两个链接的页面-一个在顶部,一个在底部。单击顶部链接时,页面必须向下滚动到存在底部链接的页面底部。单击底部链接时,页面必须向上滚动到页面顶部。




0

对于要崩溃的Bootstrap 3,如果您未在锚点上指定数据目标,而是依靠href来确定目标,则将阻止该事件。如果您使用数据目标,则需要自己阻止该事件。

<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#demo">Collapse This</button>

<div id="demo" class="collapse"> 
<p>Lorem ipsum dolor sit amet</p>
</div>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.