[前端小项目] 滚动动画 Scroll Animation (50projects50days)
📰前言
- 这个小项目源于github项目:✨50 projects 50 days, 这个项目包含了50个小型前端项目,适合学习了Html+Css+JavaScript但是还没有学习框架的前端新手作为练习。
- 这里是原项目的代码实现👉Scroll Animation Code.
- 这里是原项目的呈现效果👉Scroll Animation Live Demo.
👨🏫分析
布局
水平居中的实现较为简单,可以使用margin:0 auto;
,也可以使用flex布局:
#container{
display:flex;
flex-direction:column;
align-items:center;
}
绑定滚动事件
- 滚动事件可以考虑节流,但是这里内容比较简单,就不使用节流了(主要是不会🙊),原项目的代码也没有用节流。
- 滚动事件可以用事件监听
addEventListener()
绑定到window
对象上(也可以就绑定到document
上)。 - 触发滚动事件后,执行对应的函数——判断哪些卡片是显示的,哪些是不显示的(在窗口外部的)。
判断是否显示卡片
- 获取卡片元素,使用
querySelectorAll()
,得到一个静态的NodeList(伪数组)。 - 使用
forEach()
方法,对每一个卡片判断是否显示。 - 显示原则:当卡片的顶部到达视图窗口的顶部的距离小于视图窗口的高度时,说明卡片到达视图窗口了,便可以显示出来。
- 此处用到了
getBoundingClientRect()
方法和Window.innerHeight
属性,后者返回视图窗口的高度。 - 关于
getBoundingClientRect()
,MDN Web Docs是这样解释的:
Element.getBoundingClientRect()
方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。
语法
getBoundingClientRect()
参数
无。
返回值
返回值是一个 DOMRect 对象,是包含整个元素的最小矩形(包括 padding 和 border-width)。该对象使用 left、top、right、bottom、x、y、width 和 height 这几个以像素为单位的只读属性描述整个矩形的位置和大小。除了 width 和 height 以外的属性是相对于视图窗口的左上角来计算的。
- 在原GitHub项目给出的代码中,其判断条件是卡片使用
getBoundingClientRect()
方法后,获取top
值,然后再和Window.innerHeight
的\(\frac{4}{5}\)做比较,此处的\(\frac{4}{5}\)应该是优化参数,影响不大。
👩💻代码实现
Html
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>scroll-animation</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- 提示语句 -->
<h1>Scroll to See the Animation</h1>
<!-- 卡片列表 -->
<div id="list">
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
<div class="box">
<p>content</p>
</div>
</div>
</body>
<script src="script.js"></script>
</html>
Css
点击查看代码
*{
box-sizing: border-box;
}
body{
min-height: 100vh;
background-color: #efedd6;
display: flex;
flex-direction: column;
align-items: center;
overflow-x: hidden;
}
#list{
/* 卡片居中排列 */
display: flex;
flex-direction: column;
align-items: center;
}
#list .box{
/* 卡片通用样式 */
width: 320px;
height: 200px;
background-color:#4682b4;
display: flex;
align-items: center;
justify-content: center;
border-radius: 1rem;
box-shadow: 2px 4px 5px rgb(0 0 0 / 30%);
margin: 10px 0;
transition: transform ease 0.4s;
}
/* 偶数盒子不显示时,向右边偏移 */
#list .box:nth-of-type(2n){
transform: translateX(400%);
}
/* 奇数盒子不显示时,向左边偏移 */
#list .box:nth-of-type(2n+1){
transform: translateX(-400%);
}
#list .box p{
color: #fff;
font-size: 32px;
font-weight: bold;
}
/* 添加上.show类的盒子取消平移量,回到中间 */
#list .box.show{
transform: translateX(0%);
}
JavaScript
点击查看代码
window.onload = function(){
//获取盒子元素
const boxes = document.querySelectorAll('.box');
//判断所有盒子中,有哪些盒子是要显示出来的
function check(){
//forEach()方法是一种数组迭代方法
boxes.forEach(box=>{
//对每一个卡片判断是否显示出来
//这里使用了getBoundingClientRect()方法和window.innerHeight属性
if(box.getBoundingClientRect().top <= window.innerHeight*4/5){
box.classList.add('show');
}else{
box.classList.remove('show');
}
});
}
//绑定滚动事件
document.addEventListener('scroll',check);
//页面加载完,先判断当前视口内有哪些卡片是要显示的
check();
}
📝知识点清单
- 数组迭代方法:
forEach()
。 - 获取当前卡片在窗口的相对位置时,可以使用
getBoundingClientRect()
方法和window.innerHeight
属性进行计算、判断。 - 使用Css选择器的过程中,要注意空格的存在,比如
.box .show
(中间有空格)表示带有.box
的元素的子元素中带有.show
的元素;而.box.show
(中间无空格)则选择到了同时带有.box
和.show
这两个类的元素。
📚参考文章
[1]Element.getBoundingClientRect()
[2]Window.innerHeight
[3]CSS选择器参考手册