码云笔记前端博客
Home > 前端技术 > 利用CSS的scroll-behavior和JS的scrollIntoView使页面滚动更加平滑

利用CSS的scroll-behavior和JS的scrollIntoView使页面滚动更加平滑

2019-07-17 分类:前端技术 作者:码云 阅读(441)

本文共计3518个字,阅读时间预计9分钟,干货满满,记得点赞加收藏哦

相信大家在浏览网页的时候都见过这样的例子,当我们将页面滚动到最底部时,会出现“返回顶部”这个文字链接的时候,点击一下页面就会“唰”地一声瞬间定位到浏览器顶部,速度之快,升势之猛,以至于你没有任何反应,就像暴风雨般的爱情,让你猝不及防,脑中不断回想:“我在哪里?我是谁?我刚刚做了什么?

所有这些反应的产生,归根结底在于我们这个滚动效果实在是太干巴巴了,机械生硬没有灵性不解风情。

人是有情感的动物,既然我们做的网页是给人用的,那自然充满情感,不要那么干巴巴,让滚动效果又湿又滑,用户体验就会好。

浏览器似乎也意识到这一点,从去年年底开始,已经开始支持浏览器的原生平滑滚动定位,CSS scroll-behavior属性和JS scrollIntoView()方法都可以。

利用CSS的scroll-behavior和JS的scrollIntoView使页面滚动更加平滑

CSS scroll-behavior与平滑滚动

scroll-behavior:smooth写在滚动容器元素上,可以让容器(非鼠标手势触发)的滚动变得平滑。

初始值是'auto'。

我们先看一个实际的案例。

利用锚点定位纯CSS实现选项卡切换的技术(本质上是触发滚动条滚动)。

实现后的效果参见下GIF截屏:

锚点定位纯CSS实现选项卡切换的技术

基本功能可以满足,但有两个问题,一是由于改变location的hash实现的定位,会触发浏览器原生滚动行为,体验不好;二是选项卡内容的切换“邦邦邦”过于生硬。

于是,后来,我发明了一种基于控件元素focus触发滚动重定位的特性实现的纯CSS选项卡切换效果。

基于控件元素focus触发滚动重定位的特性实现的纯CSS选项卡切换效果

也是纯CSS实现,没有任何JavaScript代码,相比直接利用<a>元素的href锚点跳转方法,此方法不会触发浏览器外部窗体的滚动,体验更上一层楼,但是还有一个问题,那就是选项卡内容切换的时候,还是“邦邦邦”这种干巴巴的效果,并没有滑来滑去那种湿湿的效果。

不要担心,现在有了CSS scroll-behavior,则平滑滚动的问题也可以解决了。

具体实现代码如下,

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
28
29
30
31
32
<div class="tab"><label class="label" for="tab1">选项卡1</label>
<label class="label" for="tab2">选项卡2</label>
<label class="label" for="tab3">选项卡3</label></div>
<div class="box">
<div class="content">

<input id="tab1" type="text" />

我是选项卡1对应的美女

<img src="./mm1.jpg" />

</div>
<div class="content">

<input id="tab2" type="text" />

我是选项卡2对应的美女

<img src="./mm2.jpg" />

</div>
<div class="content">

<input id="tab3" type="text" />

我是选项卡3对应的美女

<img src="./mm3.jpg" />

</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
.label {
width: 100px;
margin-right: -1px;
border: 1px solid #ccc; border-bottom: 0;
padding-top: 5px; padding-bottom: 5px;
background-color: #eee;
text-align: center;
float: left;
}
.box {
height: 200px;
border: 1px solid #ccc;
scroll-behavior: smooth;
overflow: hidden;
}
.content {
height: 100%;
padding: 0 20px;
position: relative;
overflow: hidden;
}
.box input {
position: absolute; top:0;
height: 100%; width: 1px;
border:0; padding: 0; margin: 0;
clip: rect(0 0 0 0);
}

相比之前干巴巴的实现,就多了这么一句CSS——scroll-behavior:smooth:

1
2
3
4
.box {
scroll-behavior: smooth;
overflow: hidden;
}

结果一股如沐春风的交互效果扑面而来,参见下面视频截屏效果:

CSS scroll-behavior选项卡平滑滚动

一行CSS就可以锦上添花。

更简单更实际的用途

其实scroll-behavior的使用没有那么多花头,你就记住这么一句话——

凡是需要滚动的地方都加一句scroll-behavior:smooth就好了!

你别管他用不用得到,也不用管浏览器兼容性如何,你都加上。这就像一个不要钱的免费抽奖,没有中奖,没关系,又没什么损失,中奖了自然好,锦上添花!scroll-behavior:smooth就是这种尿性。

举个例子,在PC浏览器中,网页默认滚动是在<html>标签上的,移动端大多数在<body>标签上,于是,我加上这么一句:

1
html, body { scroll-behavior:smooth; }

此时,点击下面这个“返回顶部”链接,就会平滑滚动到顶部。

HTML代码如下:

1
<a href="#">返回顶部</a>

从这一点来看,业界浏览器的CSS reset都可以加上这么一条规则:

1
html, body { scroll-behavior:smooth; }

JS scrollIntoView与平滑滚动

DOM元素的scrollIntoView()方法是一个IE6浏览器也支持的原生JS API,可以让元素进入视区,通过触发滚动容器的定位实现。

随着Chrome和Firefox浏览器开始支持CSS scroll-behavior属性,顺便对,scrollIntoView()方法进行了升级,使支持更多参数,其中一个参数就是可以使滚动平滑。

语法如下:

1
2
3
target.scrollIntoView({
behavior: "smooth"
});

我们随便打开一个有链接的页面,把首个链接滚动到屏幕外,然后控制台输入类似下面代码,我们就可以看到页面平滑滚动定位了:

1
2
3
document.links[0].scrollIntoView({
behavior: "smooth"
});

JS scrollIntoView与平滑滚动

其它:

  • scrollIntoView()升级后的方法,除了支持'behavior',还有'block'和'inline'等参数,有兴趣可以参阅MDN相关文档
  • 如果我们的网页已经通过CSS设置了scroll-behavior:smooth声明,则我们直接执行target.scrollIntoView()方法就会有平滑滚动,无需再额外设置behavior参数。例如,如果你是在鑫空间原站浏览的此文章,打开控制台,执行下面代码,就可以看到平滑滚动效果了:
    1
    document.forms[0].scrollIntoView();

JS平滑滚动向下兼容处理

JS实现平滑滚动并不难,jQuery中animate()方法:

1
2
3
scrollContainer.animate({
scrollTop: 0
});

或者使用requestAnimationFrame API这类原生JS也能实现。例如下面这个我速写的个方法:

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
/**
@description 页面垂直平滑滚动到指定滚动高度
@author gwei(mybj123.com)
*/
var scrollSmoothTo = function (position) {
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
return setTimeout(callback, 17);
};
}
// 当前滚动高度
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// 滚动step方法
var step = function () {
// 距离目标滚动距离
var distance = position - scrollTop;
// 目标滚动位置
scrollTop = scrollTop + distance / 5;
if (Math.abs(distance) < 1) {
window.scrollTo(0, position);
} else {
window.scrollTo(0, scrollTop);
requestAnimationFrame(step);
}
};
step();
};

使用如下,例如,我们希望网页平滑滚动到顶部,直接:

1
scrollSmoothTo(0);

就可以了。

难的是如何支持平滑滚动的浏览器原生处理,不支持的浏览器还是使用老的JS方法处理。

我是这么处理的JS如下判断:

1
2
3
if (typeof window.getComputedStyle(document.body).scrollBehavior == 'undefined') {
   // 传统的JS平滑滚动处理代码...
}

这样就可以无缝对接了。

「除特别注明外,本站所有文章均为码云笔记原创,转载请保留出处!」

赞(5) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
5

觉得文章有用就打赏一下文章作者

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

共有 0 条评论 - 利用CSS的scroll-behavior和JS的scrollIntoView使页面滚动更加平滑

博客简介

码云笔记 mybj123.com,一个专注Web前端开发技术的博客,主要记录和总结博主在前端开发工作中常用的实战技能及前端资源分享,分享各种科普知识和实用优秀的代码,以及分享些热门的互联网资讯和福利!码云笔记有你更精彩!
更多博客详情请看关于博客

精彩评论

站点统计

  • 文章总数: 471 篇
  • 分类数目: 13 个
  • 独立页面: 8 个
  • 评论总数: 228 条
  • 链接总数: 15 个
  • 标签总数: 1033 个
  • 建站时间: 522 天
  • 访问总量: 8681006 次
  • 最近更新: 2019年11月15日