laya 创建动画
在本教程中,我们将学习如何创建如今在许多网站上看到的模式:一个固定的标头,当我们向下滚动页面时,该标头会动画化为不太吸引人的状态。 我们将从基本结构开始,然后使用CSS和纯JavaScript进行工作。 在结束之前,我们将简要介绍如何优化代码以及讨论将这种模式应用于触摸设备时所面临的挑战。
为了大致了解我们将要构建的内容,以下是演示(您可能更喜欢全屏视图 ):
HTML标记
我们将从以下标记开始这个练习:一个标头,包含一个<nav>
和几个其他嵌套元素:
<header>
<nav>
<h1>
<a href="" class="logo">Logo</a>
</h1>
<ul>
<li>
<a href="">About</a>
</li>
<li>
<a href="">Services</a>
</li>
<li>
<a href="">Portfolio</a>
</li>
<li>
<a href="">Contact</a>
</li>
</ul>
<button class="toggle-menu" aria-label="Responsive Navigation Menu">☰</button>
</nav>
</header>
<main>
<!-- content here -->
</main>
nav
元素是标头的一部分,包含三个元素; 徽标,主菜单和占位符按钮以触发响应式菜单(低于1061px)。
注意 :如果单击此按钮,将不会发生任何事情。 创建响应菜单超出了本教程的范围。
初始CSS样式
现在,让我们看一下一些CSS样式来使事情动起来:
header {
position: fixed;
top: 0;
width: 100%;
padding: 20px;
box-sizing: border-box;
background: #DD3543;
}
nav {
display: flex;
align-items: flex-end;
justify-content: space-between;
transition: align-items .2s;
}
.logo {
font-size: 2rem;
display: inline-block;
padding: 20px 30px;
background: #F35B66;
color: #fff;
margin: 50px 0 0 50px;
transition: all .2s;
}
ul {
display: flex;
margin: 50px 50px 0 0;
padding: 0;
transition: margin .2s;
}
li:not(:last-child) {
margin-right: 20px;
}
li a {
display: block;
padding: 10px 20px;
}
.toggle-menu {
display: none;
font-size: 2rem;
color: #fff;
margin: 10px 10px 0 0;
transition: margin .2s;
}
main {
display: block;
padding: 0 20px;
}
这是最重要的规则的简要说明:
-
header
元素是固定定位的元素。 - 我们使用flexbox布置
nav
元素。 - 徽标的
margin-top: 50px
和margin-left: 50px
。 另外,我们给它padding: 20px 30px
。 - 主菜单镜像徽标,其
margin-top: 50px
和margin-right: 50px
。 - 响应链接按钮被隐藏。 当视口宽度小于1061px时,它将变为可见。 此外,我们将其顶部和右侧边距设置为10px。
- 我们将
transition
属性添加到其属性值将来会更改的元素中。 这样,我们在初始状态和最终状态之间实现了平滑的过渡效果。
有了这些规则,标头看起来像这样:
动画标题
到目前为止,我们已经建立了标题的基本结构。 现在该讨论下一步了:
-
main
元素应位于标题的正下方。 请记住,标头已positioned: fixed
,因此它位于main
元素的顶部。 - 当我们向下滚动页面时,标题应该是动画的。
为了解决第一个任务,我们向main
元素添加了padding-top
属性。 此属性的值应等于标题的高度。 在本例中,我们没有为标头指定固定的高度,因此我们将使用一些JavaScript进行计算,然后将相应的填充添加到main
元素中。
为了解决第二个任务,我们将执行以下操作:
- 检索文档已经垂直滚动的像素数。
- 如果此数字大于150像素,则将
scroll
类分配给标题。
JavaScript
这是必需JavaScript代码-我们首先定义一些变量,计算header
的高度,然后将该值作为padding-top
到main
元素中:
var m = document.querySelector("main"),
h = document.querySelector("header"),
hHeight;
function setTopPadding() {
hHeight = h.offsetHeight;
m.style.paddingTop = hHeight + "px";
}
对于此演示,我们使用offsetHeight
属性检索标头的高度。 请记住,我们同样可以使用getBoundingClientRect()
方法。 值得一提的是,此方法可能返回小数值。
现在进入滚动事件:
function onScroll() {
window.addEventListener("scroll", callbackFunc);
function callbackFunc() {
var y = window.pageYOffset;
if (y > 150) {
h.classList.add("scroll");
} else {
h.classList.remove("scroll");
}
}
}
在这里,我们利用窗口的pageYOffset
属性来计算文档垂直滚动的像素数。 请注意,此属性在旧版本的IE(<9)中不起作用。 但是,如果您想支持这些版本中的任何一个,可以在此处找到解决方法。
然后,我们使用classList
属性在classList
中添加和删除scroll
类。 但是,并非所有浏览器都支持此属性,因此,如果要支持其中任何一个,则可能需要查看classList.js和classie.js polyfills 。 对于此示例,我们可以使用className
属性来操作单个类,但是在实际情况下,这可能不是理想的解决方案(如果我们有多个类)。
总结一下,我们在两种情况下调用函数:
- 页面加载时
- 并调整浏览器窗口的大小。
window.onload = function() {
setTopPadding();
onScroll();
};
window.onresize = function() {
setTopPadding();
};
CSS
只要滚动超过150px的限制,就会发生一些其他CSS规则:
.scroll {
box-shadow: 0 7px 0 0 rgba(0, 0, 0, .1);
}
.scroll .logo {
padding: 10px 20px;
font-size: 1.5rem;
}
.scroll nav {
align-items: center;
}
.scroll .logo,
.scroll ul,
.scroll .toggle-menu {
margin: 0;
}
具体来说,我们进行了以下更改:
- 将浅灰色框阴影添加到页眉。
- 减少徽标的填充和字体大小。
- 跨横轴更改弹性项目的对齐方式。
- 从徽标,菜单和响应链接按钮中删除边距。
前面提到的规则导致了新的标题布局:
响应Swift
正如我们在上一节中提到的,当视口宽度小于1061px时,我们隐藏菜单并显示响应链接按钮(实际上不执行任何操作)。 另外,我们对目标元素进行了其他一些更改。
在下面,您可以看到响应标题的初始外观:
以下是相关CSS规则:
@media screen and (max-width: 1060px) {
header {
padding: 10px;
}
nav {
align-items: center;
}
ul {
display: none;
}
.logo {
font-size: 1.8rem;
margin: 10px 0 0 10px;
}
.toggle-menu {
display: block;
}
}
动画化后的标题如下:
性能考量
现在我们设法为标头提供了所需的行为,让我们更进一步,讨论有关性能的一些事情。
在我们的示例中,在scroll
事件触发时执行了用于控制标题动画的代码(即callbackFunc
)。 这意味着可以触发数百次或更多次。 这可能会导致性能问题,尤其是当callbackFunc
函数包含许多在向上和向下滚动页面时应完成的工作时。 在我们的特定情况下,我们正在处理一个简单的动画,但是请想象一个现实世界中的场景,我们想要做更复杂的事情,例如重新定位元素等等。
那么我们该怎么办? 好了,有很多 可能的解决方案 ,但是现在让我们简要地讨论其中一种。 具体来说,我们希望我们的函数每200毫秒最多执行一次(这是一个任意值)。 为了实现此功能,我们将利用现代JavaScript实用程序库Lodash的优势。 该库提供了我们需要的节流功能。
首先,我们在项目中包含该库(很高兴,也可以选择仅合并所需的功能),然后替换此代码:
window.addEventListener("scroll", callbackFunc);
有了这个:
window.addEventListener("scroll", _.throttle(callbackFunc, 200));
要了解差异,让我们进行一个简单的测试。 我们将初始化一个计数器,该计数器在每次触发callbackFunc
函数时增加。
现在尝试上下滚动页面。 这样做时,您会注意到计数器的值大约每200ms更改一次。 接下来,重复此过程而不使用Lodash。 您会注意到计数器的值变化快得多。
同样,尽管对于我们的简单示例而言,此优化似乎不必要,但在处理昂贵且重复的任务时,应将其考虑在内。
同样,我们可以优化resize
事件侦听器。
浏览器支持
此效果在最新的浏览器和设备中有效。 但是,这种体验并非在所有移动设备(例如iOS设备)上都是理想的。 发生这种情况是因为scroll
事件在桌面浏览器上的行为与移动设备不同。 例如,在桌面浏览器上, scroll
事件连续触发,而在iPad上, 滑动事件并释放手指会发生scroll
事件。
了解了上述问题后,您应该确定是否在您的网页上使用明智的模式。
结论
在本教程中,我们创建了一个固定的标头,当向下滚动页面时该标头会显示动画。 希望您喜欢该演示,并在以后的项目中将其用作灵感!
laya 创建动画