在之前的教程中,我们学习了如何在滚动条上隐藏和显示粘性标题。今天,让我们构建一个类似的东西:一个粘性标题,其顶部(通知标题栏)将在向下滚动时消失并在向上滚动时出现。
我们正在建设什么
这是我们将要创建的内容(滚动以测试行为):
See the Pen How to Hide/Reveal Header Notification Bars on Scroll by Envato Tuts+ (@tutsplus) on CodePen.
让我们开始吧!
1. 从页面标记开始
标题将由两部分组成:顶部和底部。
顶部将包含有关免费送货的特殊通知和联系信息。
底部将包含公司徽标和菜单。默认情况下,菜单不会出现。
这种标题结构很常见,尤其是在电子商务商店中。标题/通知栏用于通知用户有关特殊折扣、促销、送货信息和其他信息。它们起着非常重要的作用,因为它们是访问者在网站上看到的第一件事。智能通知栏可以吸引更多购物者并促进销售。
除了标题之外,为了创建足够的滚动来测试效果,我们还将指定一些虚拟部分。
这是标题标记:
<header class="page-header">
<nav>
<div class="header-top">
<div class="container">
<div class="d-flex flex-column flex-row@s justify-content-between text-center">
<div>...</div>
<div>...</div>
</div>
</div>
</div><!-- /header-top -->
<div class="header-bottom">
<div class="container">
<div class="d-flex justify-content-between">
<a href="">
<img width="178" height="38" src="horizontal-logo-mobile.svg" alt="forecastr logo">
</a>
<div class="d-flex">
<ul class="menu d-flex flex-column flex-row@m align-items-center justify-content-between">...</ul>
<button aria-label="Toggle menu" class="toggle-menu">
<svg aria-hidden="true" width="30" height="30" viewBox="0 0 24 24">
<path d="M4 22h-4v-4h4v4zm0-12h-4v4h4v-4zm0-8h-4v4h4v-4zm3 0v4h17v-4h-17zm0 12h17v-4h-17v4zm0 8h17v-4h-17v4z" />
</svg>
</button>
</div>
</div>
</div>
</div><!-- /header-bottom -->
</nav>
</header>
<!-- sections here -->
2.定义一些帮助类
为了简单起见,我们将只讨论与标题相关的样式。您可以通过单击演示项目的css选项卡来检查所有项目样式。
为了设置标题的样式,我们需要一些帮助类。让我们自己定义这些类,而不是像Tailwind这样的 CSS 框架:
.container {
padding: 0 15px;
max-width: 100%;
}
.d-flex {
display: flex;
}
.flex-column {
flex-direction: column;
}
.align-items-center {
align-items: center;
}
.justify-content-between {
justify-content: space-between;
}
.text-center {
text-align: center;
}
@media (min-width: 600px) {
.container {
padding: 0 30px;
}
.flex-row\@s {
flex-direction: row;
}
}
@media (min-width: 900px) {
.flex-row\@m {
flex-direction: row;
}
}
3.指定标题样式
在小屏幕(<600px)上,标题布局将如下所示:
在 600px 和 899px 之间的屏幕上,它的布局将如下所示:
最后,在更大的屏幕(≥900px)上,它会有以下外观:
让我们注意主要样式:
顶部和底部都将是固定定位的元素,出于灵活性的原因,它们不会有静态高度。
底部将位于顶部的正下方。稍后我们会看到,我们将使用 javascript 来计算它的top属性值。
正如我们已经说过的,默认情况下,菜单是不可见的。在最大 899 像素的屏幕上,它将被绝对定位,而在更大的屏幕上,它将成为正常文档流的一部分。
以下是相关的样式:
/*CUSTOM VARIABLES HERE*/
.page-header .header-top,
.page-header .header-bottom {
position: fixed;
left: 0;
right: 0;
z-index: 1;
transition: all 0.4s;
}
.page-header .header-top {
top: 0;
padding: 10px 0;
background: var(--pink);
}
.page-header .header-bottom {
padding: 20px 0;
background: var(--white);
box-shadow: 0 -2px 10px rgb(0 0 0 / 15%), 0 5px 5px rgba(0, 0, 0, 0.15);
}
.page-header .header-bottom .menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
padding: 15px;
border-top: 1px solid whitesmoke;
transform: translateY(20px);
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.15);
background: var(--white);
transition: all 0.2s;
}
.page-header .header-bottom .menu li:not(:last-child) {
margin-bottom: 15px;
}
@media (min-width: 900px) {
.page-header .header-bottom .menu {
position: static;
padding: 0;
border: none;
margin-right: 80px;
background: none;
box-shadow: none;
}
.page-header .header-bottom .menu li:not(:last-child) {
margin: 0 30px 0 0;
}
}
4. 添加JavaScript
对于下一步,让我们向标题添加一些行为。
计算偏移量
当 dom 准备好并且我们调整浏览器窗口的大小时,该calculateOffsets()函数将触发。
该函数将负责设置top底部标题部分的padding-top属性值和body. 这些操作是必要的,因为两个标题部分都是固定元素,因此它们完全从正常的文档流中删除。
这是所需的 javaScript 代码:
calculateOffsets();
window.addeventListener("resize", () => {
calculateOffsets();
});
function calculateOffsets() {
const headerTopHeight = headerTop.offsetHeight;
const headerBottomHeight = headerBottom.offsetHeight;
headerBottom.style.top = `${headerTopHeight}px`;
body.style.paddingTop = `${headerTopHeight + headerBottomHeight}px`;
}
切换菜单
每次我们单击切换按钮时,菜单的可见性都会改变。如果它被隐藏,它就会出现,反之亦然。
以下是相关的 JavaScript 代码:
const menu = document.queryselector(".page-header .header-bottom .menu");
const toggleMenu = document.querySelector(
".page-header .header-bottom .toggle-menu"
);
toggleMenu.addEventListener("click", () => {
menu.classList.toggle("is-visible");
});
和风格:
.page-header .header-bottom .menu {
transition: all 0.2s;
}
.page-header .header-bottom .menu.is-visible {
opacity: 1;
visibility: visible;
transform: none;
}
切换标题栏
现在是本教程的主要目标。
每次我们向下滚动时,标题栏应该平滑地消失并在我们向上滚动时重新出现。
为了实现这一点,我们将遵循与上一个教程中相同的模式,因此我们将从中借用相当多的代码。
关于功能:
当我们向下滚动时,body将接收scroll-down课程。此时,顶部栏将动画到顶部并隐藏。同时,底部会向上动画并占据空白区域,另外我们会重新padding-top 计算 body.
当我们向上滚动时,它将接收scroll-up类。请注意,我们不需要这个类,但如果我们以后想通过 CSS 修改演示样式,我们可以使用它。此时,我们将从标题部分中删除 CSS 转换,并再次重新padding-top 计算 body.
如果我们滚动到页面顶部,它将失去它的scroll-up类。
这是处理所有这些东西的(相当广泛的!)JavaScript代码:
const body = document.body;
const headerTop = document.querySelector(".page-header .header-top");
const headerBottom = document.querySelector(".page-header .header-bottom");
const menu = document.querySelector(".page-header .header-bottom .menu");
const toggleMenu = document.querySelector(
".page-header .header-bottom .toggle-menu"
);
const scrollUp = "scroll-up";
const scrollDown = "scroll-down";
let lastScroll = 0;
window.addEventListener("scroll", () => {
const currentScroll = window.pageYOffset;
const headerTopHeight = headerTop.offsetHeight;
const headerBottomHeight = headerBottom.offsetHeight;
if (currentScroll <= 0) {
body.classList.remove(scrollUp);
return;
}
if (currentScroll > lastScroll && !body.classList.contains(scrollDown)) {
// down
body.classList.remove(scrollUp);
body.classList.add(scrollDown);
headerBottom.style.transform = `translateY(-${headerTopHeight}px)`;
body.style.paddingTop = `${headerBottomHeight}px`;
} else if (
currentScroll < lastScroll &&
body.classList.contains(scrollDown)
) {
// up
body.classList.remove(scrollDown);
body.classList.add(scrollUp);
headerBottom.style.transform = "none";
body.style.paddingTop = `${headerTopHeight + headerBottomHeight}px`;
}
lastScroll = currentScroll;
});
以及相关的样式:
/*CUSTOM VARIABLES HERE*/
.page-header .header-top,
.page-header .header-bottom {
transition: all 0.4s;
}
.scroll-down .header-top {
transform: translate3d(0, -100%, 0);
}
结论
就是这样,伙计们!在本练习中,我们学习了如何根据滚动方向切换通知栏。您可以主要在电子商务商店中利用这种效果来创建智能标题栏,这将增加您的销售额并进行转化。
- 计算偏移量
- 切换菜单
- 切换标题栏