项目地址
Scroll Animation
展示效果
Scroll Animation
实现思路
HTML结构比较简单,就是10+个盒子元素。当鼠标滚动时,盒子分别从左右移动过来。
思路上最开始想到的是给每一个盒子标记一个序号,滚动屏幕后,计算已经划动屏幕的距离和盒子高度的比例,得到应该移动回来的最后一个序号。这种思路当然也可以实现,但是不是最简便的方式,计算上也比较容易出现边界情况。
案例给出的方法比较简便,只需要通过Web API获取每个元素距离屏幕顶部的距离,当这个距离小于某个阈值时就移动回来,这样的好处时每个元素只需要关心自己的距离就行,不会像计算思路那样与整个内容区域强制绑定在一起,真正实现了解耦。
实现细节
HTML结构
只需要列出10+个盒子模型即可。也可以在JavaScript里循环添加这个元素。
<body><h1>Scroll to see the animation</h1><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><div class="box"><h2>Content</h2></div><script src="script.js"></script></body>
CSS样式
默认样式transform水平移动一个距离,能够做到不在可视区域内即可;为了达到左右交替移动的效果,双数位的盒子可以设置为反方向移动。等到了满足条件时,再添加一个show的class,覆盖原有的transform。
4倍的盒子宽度已经能够移出常规屏幕的可视区域了,因此这里移动是400%。
.box {background-color: steelblue;color: #fff;display: flex;align-items: center;justify-content: center;width: 400px;height: 200px;margin: 10px;border-radius: 10px;box-shadow: 2px 4px 5px rgba(0, 0, 0, 0.3);transform: translateX(400%);transition: transform 0.4s ease;
}.box:nth-of-type(even) {transform: translateX(-400%);
}.box.show {transform: translateX(0);
}
JavaScript逻辑
只需要一个函数即可,调取API的getBoundingClientRect().top得到每个盒子距离顶部的距离,当小于4/5的可视高度时,就添加show的class即可。
然后window滚动事件绑定该函数。
另外第一次加载也需要调用一次,因为此时并没有触发滚动事件,那么所有盒子都不会显示。
const boxes = document.querySelectorAll('.box')window.addEventListener('scroll', checkBoxes)checkBoxes()function checkBoxes() {const triggerBottom = window.innerHeight / 5 * 4boxes.forEach(box => {const boxTop = box.getBoundingClientRect().topif(boxTop < triggerBottom) {box.classList.add('show')} else {box.classList.remove('show')}})
}
总结
- 使用Web API的getBoundingClientRect()方法获取元素相对于viewport的位置信息
- 对每个盒子单独进行条件判断和添加class,实现逻辑的解耦