PC 浏览器平滑惯性滚动(smooth scroll)一套简单实现

前言

主要是 Bing 找了许多 libraries。效果在 Chrome for Windows 上都不理想,要么滚动很生硬,要么就是太复杂,就自己实现了。

本来是 PC only 的,写好后测试了一下移动端,是兼容的,效果也还不错……

不过反正移动端都自带惯性滑动了

效果

无惯性滚动

有惯性滚动

配色参考:https://color.adobe.com/zh/%E6%B5%81%E8%A1%8C%E8%89%B2-color-theme-4031536/

代码

HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<div class="columns" style="width: 100%;">
<div class="column">
<h3 id="无惯性滚动">无惯性滚动</h2>
<div class="ss-container">
<div class="ss-box" style="background-color: #0067A6;"></div>
<div class="ss-box" style="background-color: #00ABD8;"></div>
<div class="ss-box" style="background-color: #008972;"></div>
<div class="ss-box" style="background-color: #EFC028;"></div>
<div class="ss-box" style="background-color: #F2572D;"></div>
</div>
</div>
<div class="column">
<h3 id="有惯性滚动">有惯性滚动</h3>
<div class="ss-container" id="smooth-scrollable">
<div class="smooth-scroll">
<div class="ss-container-body" id="smooth-target">
<div class="ss-box" style="background-color: #0067A6;"></div>
<div class="ss-box" style="background-color: #00ABD8;"></div>
<div class="ss-box" style="background-color: #008972;"></div>
<div class="ss-box" style="background-color: #EFC028;"></div>
<div class="ss-box" style="background-color: #F2572D;"></div>
</div>
</div>
<div class="ss-container-hitbox"></div>
</div>
</div>
</div>
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.ss-container {
width: 100%;
height: 500px;
position: relative;
overflow-y: auto;
}
.ss-container.smooth {
overflow-y: hidden;
}
.ss-container-body {
width: 100%;
position: absolute;
transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1); /* 此处可以改变动画函数和持续时间 */
}
.ss-container-hitbox {
width: 100%;
height: 1500px; /* 高度等于滚动区域内的总高度,真实场景下可能需要动态计算 */
}
.ss-box {
width: 100%;
height: 300px;
}
.smooth-scroll {
position: -webkit-sticky;
position: sticky;
top: 0;
width: 100%;
}
Javascript
1
2
3
4
document.getElementById('smooth-scrollable').onscroll = (e) => {
const target = e.currentTarget
document.getElementById('smooth-target').style.transform = `translateY(-${target.scrollTop}px)`
}

解析

  1. 在滚动区域内增加一个 hitbox,高度等于滚动区域内的总高度,撑起滚动容器
  2. 设置滚动对象为 sticky 定位(如果滚动区域占满浏览器,也可用 fixed),并用 transform: translateY(); 控制其上下移动
  3. 监听滚动事件,并动态改变 translateY 的值
  4. 添加 CSS 动画效果 transition: transform 1s;,可以同时设置动画函数和持续时间

根据这个思路,可以封装一个 JS 库,但是我好懒……

评论