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

新手上路,请多包涵

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

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

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

原文由 Achilles 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 633
2 个回答

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

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

选项1: event.preventDefault()

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

例子:

 $('#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)

原文由 Paolo Bergantino 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

例如,

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

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

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

这是一个说明这一点的小提琴(只需将浏览器向下滚动直到获得滚动条):

http://jsfiddle.net/9dEG7/


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

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

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

使用 "#!" 的 href 只是因为它避免了这条规则。感叹号没有什么神奇之处 - 它只是一个方便的片段标识符,因为它与典型的 fragid 明显不同并且不太可能与页面上元素的 idname 匹配.事实上,我们几乎可以在散列之后放置任何东西;唯一不够用的 fragid 是空字符串、单词“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 元素的名称属性的值正好等于 fragid不是 decoded fragid ),那么树顺序中的第一个这样的元素是文档的指定部分;在这里停止算法。

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

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

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

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

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

原文由 Matt Wonlaw 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题