当我有一个与 jQuery 或 JavaScript 事件关联的链接时,例如:
<a href="#">My Link</a>
如何防止页面滚动到顶部?当我从锚点中删除 href 属性时,页面不会滚动到顶部,但链接似乎不可点击。
您需要防止发生单击事件的默认操作(即导航到链接目标)。
有两种方法可以做到这一点。
选项 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:返回false;
从事件处理程序返回 false 将自动调用 event.stopPropagation() 和 event.preventDefault()
因此,使用 jQuery,您可以选择使用这种方法来防止默认链接行为:
$('#ma_link').click(function(e) {
doSomething();
return false;
});
如果您使用原始 DOM 事件,这也适用于现代浏览器,因为 HTML 5 规范规定了这种行为。但是,旧版本的规范没有,因此如果您需要与旧浏览器的最大兼容性,您应该显式调用 .preventDefault()
。有关规范的详细信息,请参见 event.preventDefault() vs. return false (no jQuery)。
您可以将 href 设置为 #!
而不是 #
例如,
<a href="#!">Link</a>
单击时不会进行任何滚动。
当心!这仍然会在点击时向浏览器的历史记录添加一个条目,这意味着在点击您的链接后,用户的后退按钮不会将他们带到他们之前所在的页面。出于这个原因,使用 .preventDefault()
方法可能会更好,或者将两者结合使用。
这是一个 Fiddle 来说明这一点(只需向下滚动浏览器,直到出现滚动条):
http://jsfiddle.net/9dEG7/
对于规范书呆子 - 为什么这样有效:
此行为在 Navigating to a fragment identifier 部分下的 HTML5 规范中指定。 href 为 "#"
的链接导致文档滚动到顶部的原因是,此行为被明确指定为处理空片段标识符的方式:
2. 如果 fragid 是空字符串,那么文档的指示部分是文档的顶部
使用 "#!"
的 href 只是因为它避免了此规则。感叹号没有什么神奇之处 - 它只是一个方便的片段标识符,因为它与典型的 fragid 明显不同,并且不太可能匹配页面上元素的 id
或 name
。事实上,我们几乎可以在哈希之后放置任何东西;唯一不能满足要求的是空字符串、单词“top”或与页面上元素的 name
或 id
属性匹配的字符串。
更准确地说,我们只需要一个片段标识符,它将导致我们进入以下算法中的第 8 步,以便从片段中确定文档的指示部分:
将 URL 解析器算法应用于 URL,并让 fragid 成为解析后的 URL 的片段组件。如果 fragid 是空字符串,则文档的指示部分是文档的顶部;在这里停止算法。设脆弱字节是百分比解码脆弱的结果。设解码的脆弱是对脆弱字节应用 UTF-8 解码器算法的结果。如果 UTF-8 解码器发出解码器错误,则中止解码器并跳转到标记为 no decoded fragid 的步骤。如果 DOM 中有一个元素的 ID 与 decoded fragid 完全相同,那么树顺序中的第一个这样的元素就是文档的指示部分;在这里停止算法。 No decoded fragid:如果 DOM 中有一个 a 元素的 name 属性的值正好等于 fragid(未解码的 fragid),那么树顺序中的第一个这样的元素就是文档的指示部分;在这里停止算法。如果 fragid 是字符串 top 的不区分大小写的 ASCII 匹配,则文档的指示部分是文档的开头;在这里停止算法。否则,文档中没有指定的部分。
只要我们点击第 8 步并且文档中没有指定的部分,以下规则就会起作用:
如果没有指定的部分......那么用户代理必须什么都不做。
这就是浏览器不滚动的原因。
preventDefault()
的理想替代方案 - 令人遗憾的是。
一种简单的方法是利用此代码:
<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="#" 然后阻止默认事件运行更干净。
我对 this question 的第一个答案有充分的理由,例如如果被调用的函数抛出错误,return false;
将不会执行,或者您可以将 return false;
添加到 doSomething()
函数然后忘记使用return doSomething();
从您正在调用的代码中返回 false 将起作用,并且在许多情况下是首选方法,但您也可以这样做
<a href="javascript:;">Link Title</a>
当谈到 SEO 时,它实际上取决于您的链接将用于什么。如果您要实际使用它来链接到其他一些内容,那么我同意理想情况下您会在这里想要一些有意义的东西,但是如果您出于功能目的使用该链接,可能就像 Stack Overflow 对帖子工具栏所做的那样(粗体、斜体、超链接等)那么它可能并不重要。
尝试这个:
<a href="#" onclick="return false;">My Link</a>
如果您可以简单地更改 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()
行之后,否则您将永远无法到达第二行?
此外,您可以在 onclick 属性中使用 event.preventDefault 。
<a href="#" onclick="event.preventDefault(); doSmth();">doSmth</a>
无需编写额外的点击事件。
对于Bootstrap 3 for collapse,如果你没有在anchor上指定data-target,而是依靠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>
你也可以像这样简单地写:-
<a href="#!" onclick="function()">Delete User</a>
调用该函数时,请遵循 return false
示例:
<input type="submit" value="Add" onclick="addNewPayment();return false;">
创建一个包含两个链接的页面——一个在顶部,一个在底部。单击顶部链接时,页面必须向下滚动到存在底部链接的页面底部。单击底部链接时,页面必须向上滚动到页面顶部。
<a onclick="yourfunction()">
这会很好。无需添加 href="#"
你可能想检查你的 CSS。在此处的示例中:https://css-tricks.com/the-checkbox-hack/ 有 position: absolute; top: -9999px;
。这在 Chrome 上尤其愚蠢,因为 onclick="whatever"
仍会跳转到被点击元素的绝对位置。
为 display: none;
删除 position: absolute; top: -9999px;
可能会有所帮助。
event.preventDefault()
将停止滚动,但也不会将链接状态更改为 visited (color)
,这是我需要的。 “迟到 3 年”的解决方案还不算晚,而且消除了不可预见的副作用。我创建的 href 在一个循环中(由“i”索引)“#i!”,其中 i 是包含锚标记文本的数组的索引。奇迹般有效。 (只是 #i 也可以,除非我将其他 id 设置为 i)。
虽然我想使用 `href='javascript:function()'` 方法,但这会增加 11 个字节 (javascript:) 加上函数名的字节以及页面大小的参数。将其乘以 1000+ 的 href,即 16kb+ 添加到页面大小。 (是的,分页会有所帮助,但对用户没有帮助)。所以也许在不同的情况下,我会使用 javascript: 解决方案。