返回页面顶部的按钮可以让用户快速返回页面顶部,而无需花费太多精力。当页面包含大量内容或在单页网站上使用无限滚动时,这非常有用,或者在移动设备上,不同的屏幕尺寸会导致内容滚动扩展。
这些按钮通常浮动在网站的底部角落,然后在点击时将您带回页面顶部。使用 JavaScript 创建它们非常容易。但在视觉上,我们希望它不显眼,同时又足够大,以便于点击或轻触。让我们看看几种实现方法,从简单开始,然后逐步改进。
选项 1:保持简单
首先,我们在 JavaScript 中选择按钮。
var scrollToTopBtn = document.getElementById("scrollToTopBtn")
现在,document.documentElement
返回文档的根元素。我们需要它来获取偏移值。因此,接下来我们将其保存在名为 rootElement
的变量中,这样在代码中更容易调用。
var rootElement = document.documentElement
我们将在按钮上添加一个点击事件监听器
function scrollToTop {
// scroll to top logic
}
scrollToTopBtn.addEventListener("click", scrollToTop)
然后,在 scrollToTop
函数中,我们将使用 scrollTo
方法使其滚动到屏幕顶部。
function scrollToTop() {
// Scroll to top logic
rootElement.scrollTo({
top: 0,
behavior: "smooth"
})
}
我们也可以稍微调整按钮的样式
#scrollToTopBtn {
background-color: black;
border: none;
border-radius: 50%;
color: white;
cursor: pointer;
font-size: 16px;
line-height: 48px;
width: 48px;
}
现在我们可以将按钮放置在页面的某个位置,例如页脚
<footer>
<!-- Scroll to top button -->
<button id="scrollToTopBtn">☝️</button>
</footer>
我们得到的结果如下
选项 2:检测滚动位置
我们可以使用滚动事件监听器检测滚动。
function handleScroll() {
// Do something on scroll
}
document.addEventListener("scroll", handleScroll)
handleScroll
函数将在用户每次滚动时被调用。现在我们需要我们能够滚动的像素总数。
scrollHeight
给出元素的高度,包括由于溢出而不可见的部分。clientHeight
给出元素的内部高度(以像素为单位),即可见部分的高度。
如果我们将 scrollHeight
减去 clientHeight
,我们就可以得到可以垂直滚动的像素总数。
var scrollTotal = rootElement.scrollHeight - rootElement.clientHeight
现在我们有一个名为 scrollTotal
的变量,它表示可以垂直滚动的最大像素数。通过将已滚动量除以可以滚动的像素总数,我们得到 0 到 1 之间的比率。使用此比率,我们可以轻松地打开和关闭按钮。
例如,我们将添加一个条件,当用户滚动到页面总高度的 80%(或比率为 0.80)时显示滚动到顶部按钮。80% 是一个任意数字。基本上,越接近 1,用户需要滚动更多才能看到按钮。
以下是 JavaScript 代码
var rootElement = document.documentElement
function handleScroll() {
// Do something on scroll
var scrollTotal = rootElement.scrollHeight - rootElement.clientHeight
if ((rootElement.scrollTop / scrollTotal ) > 0.80 ) {
// Show button
scrollToTopBtn.classList.add("showBtn")
} else {
// Hide button
scrollToTopBtn.classList.remove("showBtn")
}
}
document.addEventListener("scroll", handleScroll)
我们需要一些 CSS 代码来在按钮进入视野时将其正确定位
.scrollToTopBtn {
/* same general styles as before */
/* place it at the bottom-right corner */
position: fixed;
bottom: 30px;
right: 30px;
/* keep it at the top of everything else */
z-index: 100;
/* hide with opacity */
opacity: 0;
/* also add a translate effect */
transform: translateY(100px);
/* and a transition */
transition: all .5s ease
}
.showBtn {
opacity: 1;
transform: translateY(0)
}
有了它,当用户滚动到页面 80% 的位置时按钮就会出现,当滚动到更高位置时按钮就会隐藏。
这似乎是一个不错的选项,设置一个事件监听器来执行此操作非常容易。但由于我们一直在检查当前滚动位置,因此性能开销可能会很大。
还有另一个选项可以解决这个问题……
选项 3:交叉观察器
交叉观察器 API 是解决上述问题的绝佳方案。它是一个相当新的浏览器 API,它允许开发人员将大多数这些任务委托给浏览器,从而实现更优化的性能。Travis Almand 撰写了关于其工作原理的 详细说明。以下是 MDN 的定义
交叉观察器 API 提供了一种异步方式来观察目标元素与祖先元素或顶级文档视窗交叉部分的变化。
非常棒!这意味着按钮可以作为我们的目标元素
// We select the element we want to target
var target = document.querySelector("footer");
然后我们编写一个回调函数,当元素与视窗“交叉”时(即进入视野时)执行某些操作。
一旦页脚进入或离开视窗,我们真正想要做的就是添加或删除一个类。回调函数接收一个条目数组作为参数。
function callback(entries, observer) {
// The callback will return an array of entries, even if you are only observing a single item
entries.forEach(entry => {
if (entry.isIntersecting) {
// Show button
scrollToTopBtn.classList.add('showBtn')
} else {
// Hide button
scrollToTopBtn.classList.remove('showBtn')
}
});
}
我们需要创建一个新的 IntersectionObserver
实例,并将刚刚编写的回调函数传递给它。
let observer = new IntersectionObserver(callback);
最后,我们告诉观察器开始观察上面选择的目标元素,以便在它与视窗交叉时进行处理
observer.observe(target);
那么平滑滚动呢?
当然可以!事实上,Chris 在 2019 年就向我们展示了如何使用 CSS 实现平滑滚动
<html id="top">
<body>
<!-- the entire document -->
<a href="#top">Jump to top of page</a>
</body>
</html>
html {
scroll-behavior: smooth;
}
这里有一些细微差别,例如 Chris 在文章中也介绍的可访问性增强。重点是,CSS 正在获得新的功能,可以完成我们以前使用 JavaScript 来完成的任务。
就是这样!我们从一个非常简单的想法开始。我们通过根据用户的滚动位置显示和隐藏按钮来对其进行了改进。然后,我们通过实现交叉观察器 API 来改进性能,而不是监视当前滚动位置。最后,我们看到了如何使用 CSS 实现平滑滚动。总而言之,我们得到一个滚动到顶部按钮,它易于查看和使用,同时不会阻塞页面上的其他元素。
请在滚动事件实现中使用节流。
谢谢
我个人认为滚动到顶部的按钮应该在用户开始向上滚动时直接显示
同意!
所有这些示例都缺少中断触发器。用户输入应该始终具有更高的优先级。如果系统开始自动滚动,我应该能够通过使用鼠标滚轮或触控板手势或触摸屏幕来中断滚动。滚动事件完成后,系统不应该继续向上滚动,这样用户就不会与系统发生冲突。
我在很多网站上都看到过这种糟糕的实现。
不错,但你可以做得更好,不要等到用户滚动到最底部才让按钮出现,这对于非常长的页面来说会更好,因为用户已经滚动了很多次才能到达页面中间。
是否有关于世界上所有“滚动到顶部按钮”使用情况的统计数据?
我只是很好奇。我很少使用它们,并且可以不用它们。
我看到这是一个很好的小型编程实践,但它会提升整体体验吗?
你会使用它们吗?
另外,请不要忘记可访问性。现在你的按钮在屏幕外时是可聚焦的,但没有标签。为了在屏幕阅读器中隐藏它,你应该添加
visibility: hidden
,当它在屏幕外时。你可以对visibility
进行过渡,使用过渡延迟让按钮在淡出之前可见。或者在聚焦时使其可见。添加
aria-label
以赋予它一些意义。我从来也没有使用过它们 :D 我对此也很感兴趣。
我认为我们可以修改按钮的不透明度,以便在向下滚动时使其逐渐可见。如果它只在我们接近页脚时才出现,那么我们只需将其放在页脚中即可(无需使用 JS,只需一个简单的链接)。但是,用户需要看到这样的按钮可用,而不仅仅是在滚动到页面长度的 80% 之后才出现。
为什么按钮不能在开始向下滚动时立即出现,比如当滚动页面长度超过 100vh 时?
谢谢。非常好的文章。我建议包含一个纯 CSS 替代方案,例如这个笔提供的方案。
– 纯 CSS 滚动到顶部
我从未注意到有人使用过这样的按钮。
恕我直言,几乎每个人都使用 Home/Pos1 键...
一个返回页面顶部的按钮允许用户快速返回页面顶部,而无需过多努力。当页面有很多内容时,这非常有用。
如果它也能在 IE 中工作就好了。有人知道什么变通办法吗?
如何只在从某个点开始向上滚动时显示返回顶部?我找不到任何示例。
不错。但是
如果“滚动到顶部按钮”在用户开始滚动时出现会更好。简单的解决方案:更改片段中的目标。像这样
我真的希望这不会是双重发布,如果是,请删除!
如何让滚动到顶部按钮在标题消失时出现?例如
有没有办法做到这一点,但让按钮在您距离标题一定像素(例如标题下方 500 像素)时出现?
我不想让它太早出现。