在本教程中,我们将学习如何在向下滚动页面时隐藏页眉,然后在向上滚动时显示它。作为奖励,我们还将使标题菜单功能齐全。
为什么要使用粘性组件?
粘性组件(例如标题)在网页设计领域非常流行;他们可以将基本的 UI 元素永久保留在视图中,并且在用户需要时可以轻松访问。但是,在某些情况下(如果标题包含大量内容,或者视口大小和方向限制了可用屏幕空间的数量)粘性标题可能会很突兀。
“如果实施错误,粘性导航元素可能会分散实际内容的注意力。” —— 亚伦·安德烈·奇奇奥科
在不需要时(即:当用户滚动查看更多内容时)从视图中消失的粘性标题是一个很好的折衷方案。
我们可以通过使用像Headroom.js这样的外部库来实现这种效果,但我们将通过自己构建一些东西来学习底层的机制。作为奖励,我们还将使标题菜单功能齐全,供您添加自己的自定义。
我们正在建造什么
这是我们将要创建的内容(滚动以测试行为):
See the Pen Toggle Header Depending on Scrolling Direction ?? by Envato Tuts+ (@tutsplus) on CodePen.
让我们开始吧!
1. 从页面标记开始
标记将包含以下元素:
Aheader将包含一个nav. 在其中,我们将放置菜单切换按钮和菜单本身。
来自LottieFiles 库的Lottie 动画。每次我们向下滚动时都会播放。单击后,将出现菜单。
只是为了用一些虚拟内容来丰富页面,我们还将定义三个全屏部分。我们将添加一些取自之前教程的背景图片。
这是页面标记:
<header class="page-header">
<nav>
<div class="trigger-menu-wrapper">
<button class="trigger-menu">
<svg width="20" height="20" viewBox="0 0 24 24">
<path d="M24 10h-10v-10h-4v10h-10v4h10v10h4v-10h10z"/>
</svg>
<span>MENU</span>
</button>
</div>
<ul class="menu">...</ul>
</nav>
</header>
<a href="" role="button" aria-label="Toggle menu" class="lottie-wrapper">
<lottie-player src="https://assets10.lottiefiles.com/datafiles/9gIwZ2uiiKglyb0/data.json" style="width: 60px; height: 60px;"></lottie-player>
</a>
<main class="page-main">
<section>...</section>
<section>...</section>
<section>...</section>
</main>
值得一提的是,为了使 Lottie 动画可点击,我们将它包裹在一个链接上,该链接将具有role="button". 通常,我们会将它包裹在一个button元素周围。但是,由于lottie-player发出divs,将 a 放在 a中在语义上是不正确的。divbutton
2. 添加粘性标题css
让我们添加一些 CSS 规则来改进我们的标题和动画的外观和(在一定程度上)行为方式。
为简单起见,我不会介绍初始重置样式,但可以通过单击演示项目的CSS 选项卡随意查看它们。
标题和动画样式非常简单,但有两点很重要:
首先,切换菜单包装器、菜单和 Lottie 动画将是固定定位的元素。
其次,菜单和 Lottie 动画最初将被隐藏。
相关样式如下:
/*CUSTOM VARIABLES HERE*/
.trigger-menu-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
padding: 20px;
z-index: 2;
background: var(--lightpurple);
transition: transform 0.4s;
}
.page-header .trigger-menu {
display: flex;
align-items: center;
font-size: 1.3rem;
color: var(--white);
letter-spacing: .2em;
}
.page-header .trigger-menu svg {
fill: var(--white);
margin-right: 8px;
transition: transform 0.3s;
}
.page-header .menu {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
text-align: center;
padding: 15vh 0 5vh;
overflow: auto;
z-index: 1;
background: var(--lightpurple);
}
.page-header .menu a {
font-size: 3rem;
}
.page-header .sub-menu a {
font-size: 1.5rem;
}
.lottie-wrapper {
position: fixed;
bottom: 50px;
right: 25px;
z-index: 1;
padding: 5px;
border-radius: 5px;
}
这些部分将表现为全屏元素,带有背景图像和顶部的深色叠加层。这些会给我们一些滚动过去的东西,这样我们就可以看到标题的隐藏/显示行为:
.page-main section {
position: relative;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
height: 100vh;
}
.page-main section::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.25);
}
3. 添加javascript
下一步,让我们为菜单添加一些行为。
切换菜单
每次我们单击切换按钮时,菜单的可见性都会改变。如果它被隐藏,它会出现。但如果它是可见的,它就会消失。
我们正在以非常基本的方式处理此问题,但它使您有可能根据自己的喜好定制事物。
这是所需的 JavaScript 代码:
const body = document.body;
const triggerMenu = document.queryselector(".page-header .trigger-menu");
triggerMenu.addeventListener("click", () => {
body.classList.toggle("menu-open");
});
以及相关的样式:
.page-header .trigger-menu svg {
transition: transform 0.3s;
}
.menu-open {
overflow: hidden;
}
.menu-open .page-header .menu {
display: block;
}
.menu-open .page-header svg {
transform: rotate(45deg);
}
您可能已经注意到,在菜单状态的变化过程中没有任何动画。发生这种情况是因为我使用了非动画 display属性。如果您想添加某种动画,请将此属性替换为可动画的东西,例如opacityor visibility。
切换标题
现在让我们把注意力转向更有趣的事情。
每次我们向下滚动时,切换按钮(以及一般的标题)应该随着滑出动画而消失,而 Lottie 动画将开始播放。如果我们然后向上滚动,它应该会出现一个滑入动画,而 Lottie 动画将停止。
注意:对于本教程,我们将使用LottieFiles 网络播放器嵌入 Lottie 动画。如果您想了解更多信息,请花一些时间阅读这篇文章。无论如何,这个过程是可选的,超出了这个项目的主要重点。
为了实现这个功能,我们将使用两个帮助类: scroll-up和scroll-down. 进一步来说:
当我们向下滚动时,body将接收scroll-down课程。
当我们向上滚动时,它将接收scroll-up课程。
如果我们滚动到页面顶部,它将失去它的scroll-up类。
为了检测滚动方向,我们将最后滚动位置存储在变量 ( lastScroll) 中。最初,该变量的值为 0。然后,当我们滚动时,我们将检查新位置是否大于或小于旧位置。根据该条件的结果,我们将相应的类应用于body.
这是处理该问题的 javaScript 代码:
const body = document.body;
const nav = document.querySelector(".page-header nav");
const menu = document.querySelector(".page-header .menu");
const lottiePlayer = document.querySelector("lottie-player");
const scrollUp = "scroll-up";
const scrollDown = "scroll-down";
let lastScroll = 0;
window.addEventListener("scroll", () => {
const currentScroll = window.pageYOffset;
if (currentScroll <= 0) {
body.classList.remove(scrollUp);
return;
}
if (currentScroll > lastScroll && !body.classList.contains(scrollDown)) {
// down
body.classList.remove(scrollUp);
body.classList.add(scrollDown);
lottiePlayer.play();
} else if (
currentScroll < lastScroll &&
body.classList.contains(scrollDown)
) {
// up
body.classList.remove(scrollDown);
body.classList.add(scrollUp);
lottiePlayer.stop();
}
lastScroll = currentScroll;
});
以及相关的样式:
/*CUSTOM VARIABLES HERE*/
.
trigger-menu-wrapper {transition: transform 0.4s;
}
.scroll-down .trigger-menu-wrapper {
transform: translate3d(0, -100%, 0);
}
.scroll-down .lottie-wrapper {
background: var(--darkgray);
}
.scroll-up .trigger-menu-wrapper {
transform: none;
}
.scroll-up:not(.menu-open) .trigger-menu-wrapper {
background: var(--lightpurple);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.35);
}
通过 Lottie 动画切换菜单
正如我们已经讨论过的,当我们向下滚动时,将播放 Lottie 动画。
此时,我们将能够单击动画并打开菜单。请注意,在此状态下,菜单切换菜单将被隐藏。
下面是相应的 JavaScript 代码:
const body = document.body;
const triggerMenu = document.querySelector(".page-header .trigger-menu");
const lottieWrapper = document.querySelector(".lottie-wrapper");
const lottiePlayer = lottieWrapper.querySelector("lottie-player");
lottieWrapper.addEventListener("click", (e) => {
e.preventDefault();
triggerMenu.click();
body.classList.toggle("menu-open-with-lottie");
});
以及相关的样式:
.menu-open-with-lottie .page-header .menu {
padding: 5vh 0;
}
结论
就是这样,伙计们!在本练习中,我们学习了如何根据滚动方向切换粘性标题的可见性。
- 为什么要使用粘性组件?
- 切换菜单
- 切换标题
- 通过 Lottie 动画切换菜单