效果预览

思路讲解

在我的个人主页中,上下滑动(滚动)时会有一个缓冲的效果。
其实在一些非常好的网站里也会用到滑动阻尼的效果。它会使用户的交互体验得到一个非常棒的提升。

通常来说,也可以使用CSS的 scroll-behavior 属性,这个属性是可以让你在滑动容器时提供平滑的滚动行为。
但是,这个属性暂时不是我想要的阻尼效果。

滑动原理

添加一个缓动效果,使用一个容器.scrollbox,使用 transition 属性,实现滑动缓冲效果时长。

固定窗口,将我们的浏览器窗口固定在原位。
首先我们要明白一点,为什么我们的浏览器窗口可以上下移动?那是因为页面内容超过浏览器窗口大小,从而body大小改变,出现滚动条,使触发浏览器窗口滚动。

所以先将整个网页内容大小固定起来,将它设置为窗口大小。再为它添加个容器,使得它跟我们浏览器窗口大小相同。

再添加容器.viewbox,使用 fixed 属性,将它固定在浏览器顶端。
这个时候就可以使用JS来监听滚动事件。

首先获取.scrollbox的实际高度,然后将其的高度设为body的高度。(offsetHeight包括边框和内部空白补丁)
最后要做的就是,当我们滚动的时候,为.scrollbox添加一个 transform 属性移动即可。

效果实现

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滑动阻尼</title>
<style>
* {
font-size: 2vmin;
margin: 0;
padding: 0;
}

::-webkit-scrollbar {
display: none;
}

body {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
background-color: #171717;
}

.scrollbox {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
flex-shrink: 0;
transition: .3s ease-out;
}

.viewbox {
position: fixed;
top: 0;
display: flex;
align-items: flex-start;
width: 100%;
height: 100vh;
overflow: hidden;
}

.box {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-size: calc(18px + 1vw);
font-weight: bold;
}

</style>
</head>

<body>
<div class="viewbox">
<div class="scrollbox">
<div class="box" style="background-color: #17f700;">#17f700</div>
<div class="box" style="background-color: #ffc93e;">#ffc93e</div>
<div class="box" style="background-color: #0084FF;">#0084FF</div>
<div class="box" style="background-color: #FF3842;">#FF3842</div>
<div class="box" style="background-color: #d44040;">#d44040</div>
</div>
</div>
</body>
<script>
let scrollbox = document.getElementsByClassName("scrollbox")[0];
function resize_body() {
let height = scrollbox.offsetHeight;
document.body.style.height = `${height}px`;
};
function scroll() {
scrollbox.style.transform = `translateY(${-scrollY}px)`;
};
window.addEventListener("scroll", scroll);
window.addEventListener("load", resize_body);
window.addEventListener("resize", resize_body);
</script>

</html>

进阶优化

在移动端部分浏览器内访问时,滑动的时候大多会有Bug出现,初步个人理论推测应该是和本身的滑动策略冲突导致的。所以我在个人主页里的滑动阻尼效果进行了优化。

在移动端时移除了滑动阻尼的效果,使用 scroll-behavior: smooth; 处理滚动的平滑效果。(实在想不出好的办法来解决)

而JS上我使用的是 document.body.clientWidth >= 768 进行判断,当屏幕宽度小于768时,将body和.scrollbox的效果清除。